【问题标题】:How to reset two-dimensional array to its original form after sorting?排序后如何将二维数组重置为原始形式?
【发布时间】:2019-08-02 01:33:38
【问题描述】:

在使用冒泡排序对其进行排序后,我正在尝试将 2D 数组重置为其原始形式。我需要将其重置为排序前的状态。我该怎么做?如果您有一个问题,为什么数组是全局的。这是一项学校作业,这就是我们的教授希望我们这样做的方式。 这是我的程序:

 #include<iostream>

    using namespace std;
    const int NUM_COLS=4;
    const int NUM_ROWS=5;       

    int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
                            {9, 8, 10, 17},
                            {4, 7, 11, 18},
                            {2, 5, 9, 12},
                        {7, 9, 4, 10}};

它使用bubbleSort对数组进行排序

void bubbleSort(int row, int col){}

是显示数组函数头

void displayArray(){}

这里是主要功能

int main(){



        cout<<"original array"<<endl;
        displayArray();

        bubbleSort(NUM_ROWS-1, NUM_COLS);
        cout<<"\nbubble sort"<<endl;
        displayArray();

        reset();
        displayArray();
        return 0;
    }

现在我需要将数组重置为原始数组。我这样做了,但它不起作用。

void reset(){

 int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
                                {9, 8, 10, 17},
                                {4, 7, 11, 18},
                                {2, 5, 9, 12},
                                {7, 9, 4, 10}};
}

【问题讨论】:

  • 这是不可能的,元素的初始顺序不会保留在任何地方。您必须创建数组的副本。
  • 你能详细说明一下吗?我一直在互联网上寻找答案,我找到了诸如“创建副本”之类的答案,但是当我尝试这样做时却没有用。
  • 排序前先复制一份。或者,对std::reference_wrapper 的新容器进行排序,以获得原始容器的排序视图
  • 您正在reset() 中创建一个新数组,但无论如何您都不能分配给普通数组。考虑使用std::array,这样你就可以重新分配=

标签: c++ arrays reset dimensional


【解决方案1】:

您的reset 正在声明一个新数组(并且什么都不做)。您不能分配 (=) C 样式数组,因此您需要一些看起来不同的东西。如果您可以改用std::array,则可以在reset 中分配。

#include <array>

const int NUM_COLS=4;
const int NUM_ROWS=5;       

std::array<std::array<int, NUM_ROWS>, NUM_COLS> values = {
    {5, 3, 2, 16},
    {9, 8, 10, 17},
    {4, 7, 11, 18},
    {2, 5, 9, 12},
    {7, 9, 4, 10}};

// Other code probably remains unchanged

void reset() {
    values = {
        {5, 3, 2, 16},
        {9, 8, 10, 17},
        {4, 7, 11, 18},
        {2, 5, 9, 12},
        {7, 9, 4, 10}};
}

此时你会发现你的界限是错误的,它应该是

const int NUM_COLS=5;
const int NUM_ROWS=4;       

或不同形状的数组初始化器。

【讨论】:

  • +1 但你不应该有:std::array&lt;std::array&lt;int, NUM_COLS&gt;, NUM_ROWS&gt; values ... 然后原来的二维数组可以工作吗?我还认为您需要额外的大括号以免混淆编译器,例如:values = {{{5, 3, 2, 16}, {9, 8, 10, 17}, {4, 7, 11, 18}, {2, 5, 9, 12}, {7, 9, 4, 10}}};
【解决方案2】:
void reset(){
  static int original[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
                                {9, 8, 10, 17},
                                {4, 7, 11, 18},
                                {2, 5, 9, 12},
                                {7, 9, 4, 10}};

  for (int i = 0; i < NUM_ROWS; i++)
    memcpy(array[i], original[i], NUM_COLS * sizeof(int));
}

不是最漂亮的东西,但这应该可以。既然你的教授希望你这样做,那就去做吧¯\_(ツ)_/¯

【讨论】:

  • 这不是用错了边界吗?您有 NUM_ROWSint[NUM_COLS] 实例
  • 我会考虑使用std::copy(std::begin(*original), std::begin(*original) + NUM_ROWS * NUM_COLS, std::begin(*array)) 而不是那个循环和memcpy
  • @fdan 我不确定矩阵是否会在内存中正确对齐,但是是的,也许。不过我还是会选择memcpy(array, original, NUM_ROWS * NUM_COLS * sizeof(int))。如果教授要求int[][],他们可能不希望人们使用std::copy。理想情况下,使用 C++ STL 是可行的方法,是的,但你永远不知道。
【解决方案3】:

正如我在评论中所说,分配数组的最简单方法是将它们包装在一个结构中。瞧,突然之间,C++ 发展出了它甚至不知道它从 C 继承来的能力并复制了数组!1甚至是嵌套的多维数组!

#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;

const int NUM_COLS=4;
const int NUM_ROWS=5;       

// Define a struct (i.e., a class with all public members)
// which has just a single member, the array. Note that this is
// only a *type* declaration, no object is created yet.
struct arrT
{
  int array [NUM_ROWS][NUM_COLS];
};

// object creation.
arrT workArr;

void reset()
{
  // The initialization value is hidden inside the function.
  // static variables are initialized only once, for constant 
  // data at compile time.
  static const arrT oriArr 
  {
    { {5, 3, 2, 16},
      {9, 8, 10, 17},
      {4, 7, 11, 18},
      {2, 5, 9, 12},
      {7, 9, 4, 10}
    }
  };

  workArr = oriArr; // simple default assignment of structs
}

// The parameters are redundant.
void stdSort(int /*row*/, int /*col*/)
{ 
  // Sort the 2D array as a one-dimensional sequence
  // (which the elements are in memory).
  // The algorithm expects iterators to the first and
  // one-after-the-last elements in the sequence. Pointers
  // to the elements in an array are perfectly good iterators.
  std::sort(&workArr.array[0][0], &workArr.array[NUM_ROWS-1][NUM_COLS]);
}

void displayArray()
{
  // The top-level elements of a 2D array are the rows...
  for(auto &row: workArr.array)
  {
    // ... and the elements of the rows are ints. 
    // Note how the
    // dimensions are known from the class declaration.
    for(auto &el: row)
    {
      cout << setw(4) << el;
    }
    cout << "\n";
  }
}

int main(){

  cout << "Work array before initialization:\n";
  displayArray();

  reset(); // before, the values of the global array are 0.
  cout<<"\nWork array after init:\n";
  displayArray();

  stdSort(NUM_ROWS, NUM_COLS);
  cout<<"\nWork array after std sort"<<endl;
  displayArray();

  reset();
  cout << "\nWork array after reset\n";
  displayArray();
  return 0;
}


1 数组是我所知道的唯一例子,其中生成的默认赋值运算符的成员赋值可以分配一个没有独立赋值运算符的类型(这是确切原因我们跳过这个圈)。还有其他人吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-03
    • 2013-12-04
    • 1970-01-01
    • 2021-01-02
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多