【问题标题】:Sorting multidimensional array in c++在 C++ 中对多维数组进行排序
【发布时间】:2013-11-21 19:57:27
【问题描述】:

我是编程初学者,但遇到了问题。 我必须创建二维数组 [5][3] ... 让我们说这是其中一部分的示例:

  1. 2 3 4
  2. 7 8 9
  3. 5 6 7

然后我必须得到行的总和并将其写在此旁边:

  1. 2 3 4 9
  2. 7 8 9 24
  3. 5 6 7 18

现在,我必须按这个总和对数组进行排序,所以结果如下所示:

  1. 7 8 9 24
  2. 5 6 7 18
  3. 2 3 4 9

我不知道如何实现,这是我的代码:

    #include <iostream>
    #include <time.h>
    using namespace std;


    void tocke(int polje[5][3])
    {
      int vsota;
       srand(time(NULL));
       int sums[5];
for (int i = 0; i < 5; i++)
{
    vsota = 0;
    cout << endl;
    cout << i + 1 << ". ";

    for (int j = 0; j < 3; j++){
        polje[i][j] = (rand() % 10 + 1);
        vsota += polje[i][j];
        sums[i] = vsota;
        cout << polje[i][j] << "  ";
    }
}   
    }

    void urejaj(int polje[5][3])
    {
cout << "\n\n\n\n" << endl;
int sums[5];
int vsota ;
double temp;




for (int i = 0; i < 5; i++)
{
    vsota = 0;
    cout << endl;
    cout << i + 1 << ". ";
    for (int j = 0; j < 3; j++)
    {

        vsota += polje[i][j];
        sums[i] = vsota;

        if (sums[i] < sums[i+1])
        {

            temp = polje[i][j];
            polje[i][j] = polje[i + 1][j];
            polje[i + 1][j] = temp;

        }

        cout << polje[i][j] << " ";

    }cout << sums[i];

    }

    }











   int main()
    {
int polje[5][3];
tocke(polje);
urejaj(polje);
cout << "\n";
system("pause");
return 0;


   }

第一个函数在字段中写入元素,第二个函数必须对字段进行排序。

【问题讨论】:

  • 求和后,尝试将数组复制到新数组,但顺序正确。
  • 你可以创建一个比较两个多维数组的函数,然后比较前两个数组,然后将前两个数组的结果与第三个数组比较?

标签: c++ arrays sorting


【解决方案1】:

通过更改数据结构,您的问题可能会更容易解决。与其拥有一个数组数组,不如拥有一个结构数组。该结构将包含总和和值数组。

struct Row
{
  int sum;
  std::vector<int> values;
};

Row data[5];

使用此概念,您可以按总和对行进行排序。
你可以很容易地为此编写一个比较器并使用std::sort

bool Compare_Rows(const Row& a, const Row &b)
{
  return a.sum < b.sum;
}

//...
std::sort(&data[0], &data[5], Compare_Rows);

编辑1——重载运算符
您可以通过提供重载运算符&lt; 来简化并且不需要比较器:

struct Row
{
  int sum;
  std::vector<int> values;

  bool operator<(const Row& other)
  {
    return sum < other.sum;
  }
};

排序调用现在变为:

std::sort(&data[0], &data[5]);

【讨论】:

  • “OOPs”又做了一次 ;) +1。代替Compare_Rows,我们可以有一个重载的`operator
  • sum 永远不会被分配,是吗?
  • @BrianGradin:成员 sum 留给 O.P. 计算。 values 成员也应由 O.P. 填写
  • 在内置数组上使用非成员 beginend。使用std::sort(std::begin(data), std::end(data)),参数变得更加通用,并且可以在以后更改容器而无需更改此代码。
  • 这很有帮助,但它必须与我的代码更相似,因为它是针对学校的,而且锻炼的规则是,它必须具有两个功能,正如我在代码中所写的那样:) 还是谢谢你
【解决方案2】:

如果你仍然迷路,这里是完整的程序:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std;

void display_matrix(int**, int, int);
void gen_matrix(int**, int, int);
void gen_matrix_sum(int**, int**, int, int);
void sort_matrix(int**, int**, int, int);

int main()
{
    srand(time(0));
    int m=5, n=3;

    int** my_matrix = (int**)malloc(m*sizeof(int*));
    for (int i=0; i<m; i++) my_matrix[i] = (int*)malloc(n*sizeof(int));
    gen_matrix(my_matrix, m, n);
    display_matrix(my_matrix, m, n);
    cout << endl;

    int** my_matrix_sum = (int**)malloc(m*sizeof(int*));
    for (int i=0; i<m; i++) my_matrix_sum[i] = (int*)malloc((n+1)*sizeof(int));
    gen_matrix_sum(my_matrix_sum, my_matrix, m, n);
    display_matrix(my_matrix_sum, m, n+1);
    cout << endl;

    int** my_matrix_sorted = (int**)malloc(m*sizeof(int*));
    for (int i=0; i<m; i++) my_matrix_sorted[i] = (int*)malloc((n+1)*sizeof(int));
    sort_matrix(my_matrix_sorted, my_matrix_sum, m, n);
    display_matrix(my_matrix_sorted, m, n+1);   
    cout << endl;
}

void display_matrix(int** my_matrix, int m, int n)
{
    for (int i=0; i<m; i++)
    {
        for (int j=0; j<n; j++)
            cout << setw(2) << my_matrix[i][j] << " ";
        cout << endl;
    }
}

void gen_matrix(int** M, int m, int n)
{
    int random_limit = 10;

    for (int i=0; i<m; i++)
        for (int j=0; j<n; j++)
            M[i][j] = rand()%random_limit + 1;
}

void gen_matrix_sum(int** M, int** my_matrix, int m, int n)
{
    int aux[m];

    for (int i=0; i<m; i++)
        aux[i] = 0;

    for (int i=0; i<m; i++)
        for (int j=0; j<n; j++)
        {
            M[i][j] = my_matrix[i][j];
            aux[i] += M[i][j];
        }

    for (int i=0; i<m; i++)
        M[i][n] = aux[i];   
}

void sort_matrix(int** my_matrix_sorted, int** my_matrix, int m, int n)
{
    int v_sum_values[m];

    for (int i=0; i<m; i++)
        v_sum_values[i] = my_matrix[i][n];

    int v[n];   
    int max = v_sum_values[0];
    int index;
    for (int i=0; i<m; i++)
    {

        for (int j=0; j<m; j++)
        {
            if (v_sum_values[j]>max)
            {
                max = v_sum_values[j];
                index = j;
            }
        }
        v_sum_values[index] = -1;
        v[i] = index;   
        max = v_sum_values[i];
    }

    for (int i=0; i<m; i++)
        for (int j=0; j<n+1; j++)
            my_matrix_sorted[i][j] = my_matrix[v[i]][j]; 
}

【讨论】:

  • 这很有帮助,但它必须与我的代码更相似,因为它适用于学校,而且练习规则是,它必须具有两个功能,正如我在代码中所写:) 还是谢谢你
【解决方案3】:

这是我解决问题的方法:

编写一个交换函数,用于切换多维数组中的两行。比如:

// columns is the number of columns; ie array[rows][columns]
void swap(int[][] array, const int columns, int switch1, int switch2)
{
    for (int i = 0; i < columns; i++)
        array[switch1][i] ^= array[switch2][i] ^= array[switch1][i] ^ array[switch2][i];
}

然后,编写一个 sum 函数,将所有元素相加。比如:

int sumCol(int[][] array, int columns, int index)
{
    int sum = 0;
    for (int i = 0; i < columns; i++)
        sum += array[index][i];
    return sum;
}

最后,编写一个排序函数,它能够使用以下操作对多维数组进行排序:

  • 比较两行的总和
  • 交换两行

我会让你决定使用哪种排序算法。

【讨论】:

    【解决方案4】:

    我必须创建二维数组

    我不知道你的意思是什么(你必须从一些输入中读取它,还是用数字等填充它?),但假设你创建了一个这样的二维矩阵:

    // Just a type alias for the matrix.
    template <typename T, std::size_t R, std::size_t C>
    using Matrix = std::array<std::array<T, C>, R>;
    
    // Create two dimensional matrix [3][3] of ints.
    Matrix<int, 3, 3> matrix = {{ { 2, 3, 4 },
                                  { 7, 8, 9 },
                                  { 5, 6, 7 } }};
    

    然后您可以按每行的总和按降序对矩阵进行排序,如下例所示。我使用了std::sort 和一个自定义的比较器仿函数(使用 lambda 函数创建):

    std::sort(std::begin(matrix), std::end(matrix), [] (decltype(*matrix.cbegin())& lhs, decltype(*matrix.cbegin())& rhs) {
        return std::accumulate(std::begin(lhs), std::end(lhs), 0) > std::accumulate(std::begin(rhs), std::end(rhs), 0);
    });
    

    就是这样。

    现在让我们输出矩阵:

    for (decltype(matrix.size()) row = 0; row != matrix.size(); ++row) {
        std::cout << row + 1 << ". ";
        for (const auto i : matrix[row]) {
            std::cout << i << " ";
        }
        std::cout << std::accumulate(std::begin(matrix[row]), std::end(matrix[row]), 0);
        std::cout << std::endl;
    }
    

    Live example

    【讨论】:

    • 这很有帮助,但它必须与我的代码更相似,因为它适用于学校,而且练习规则是,它必须具有两个功能,正如我在代码中所写:) 还是谢谢你
    猜你喜欢
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2010-10-13
    相关资源
    最近更新 更多