按特定顺序重新排序矩阵中的行

时间:2016-07-24 08:32:09

标签: c arrays algorithm

我成功地将计算出的子集存储在C语言的二维数组矩阵中。现在我想按照所需的顺序打印子集。 例如。 二维阵列矩阵

  

10 7 3 2 1

     

10 7 5 1

     

7 6 5 3 2

     

10 6 5 2

     

10 7 6

期望输出

  

10 7 6

     

10 7 5 1

     

10 7 3 2 1

     

10 6 5 2

     

7 6 5 3 2

如何快速排序以对这些行进行排序/排序?

4 个答案:

答案 0 :(得分:0)

首先,你确定第3行第5列的 1 应该在那里,而不是在最后一行吗?

无论如何,实现目标的有效方法是:

  • 计算频率数组
  • 声明一个新矩阵
  • 从频率数组中取出最高元素(在您的情况下为10)并使用您想要的格式放入矩阵。

这是节省时间的,因为您不使用任何排序算法,因此您不会在那里浪费时间。 它不是节省空间的,因为你使用2个矩阵和1个数组,而不是其他帖子中建议的1个矩阵,但这不应该是一个问题,除非你使用数百万行和列的矩阵

频率数组的C代码:

int freq[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(int i=0; i<NO_ROWS; i++) {
  for(int j=0; j<NO_COLS; j++) {
    if(MATRIX[i][j]!=null && MATRIX[i][j]>0 && MATRIX[i][j]<11) {
      freq[MATRIX[i][j]]++;
    }
  }
}

用于计算新矩阵维度的C代码 (假设你想保留行数)

OUTPUT_MATRIX[100][100] /*I declared it statically, but I would advise to make it dinamically */
/* first, compute the number columns. 
To do so, we need the number of elements 
(we get them by simply summing up frequency array's elements) */
int s=0;
for(int i=0; i<11; i++) {
  s+=frequency[i];
}
int addOne = 0 /* boolean value to check if we will have to add one extra column for safety */
if(s % NO_ROWS) {
  addOne = 1; /* division is not even, so we will have to add extra column */
}
NO_COLS = s/NO_ROWS + addOne;

现在,最后一部分,将频率数组中的值分配给OUTPUT_MATRIX

int k=0;
int currentNumber = 10; /* assigning starts from 10 */
for(int i=0; i<NO_ROWS; i++) {
  for(int j=0; j<NO_COLS; j++) {
    if(currentNumber>0) {
      if(frequency[currentNumber]==0 || k>=frequency[currentNumber]) {
        currentNumber--;
        k=0;
      }
      OUTPUT_MATRIX[i][j] = frequency[currentNumber];
      k++;
    } else {/*here, you can assign the rest of the value with whatever you want
            I will just put 0's */
      OUTPUTMATRIX[i][j] = 0;
    }
  }
}

希望这有帮助!

答案 1 :(得分:0)

正如@chqrlie所说,这可以通过qsort轻松解决。

取决于声明矩阵的方式(它是指向int数组的指针数组吗?所有数组都具有相同的长度吗?它是一个固定大小的全局数组吗?)代码必须做稍微不同的事情

因此,假设数组是一个全局变量,并且所有行都具有相同的长度(用0填充):

<强> MWE:

#include <stdio.h>
#include <stdlib.h>

/*
 Compare 2 integers
 returns:
     -1 if *i1 < *i2
     +1 if *i1 > *i2
      0 if *i1 == *i2
 */
int intcmp(const int *i1, const int *i2)
{
    return (*i2 < *i1) - (*i1 < *i2);
}

#define ROWS 5
#define COLS 5

/*
  Assumes rows already sorted in descending order

  NOTE: qsort calls the comparison function with pointers to elements
  so this function has to be tweaked in case the matrix is an array of
  pointers. In that case the function's declaration would be:

  int rowcmp(int **pr1, int **pr2)
  {
       const int *r1 = *pr1;
       const int *r2 = *pr2;
       // the rest is the same
  }
 */
int rowcmp(const int *r1, const int *r2)
{
    int i = 0, cmp;

    do {
        cmp = intcmp(&r1[i], &r2[i]);
        i++;
    } while (i < COLS && cmp == 0);

    return -cmp; /* return -cmp to sort in descending order */
}

int data[5][5] = {
    {10,7,3,2,1},
    {10,7,5,1,0},
    { 7,6,5,3,2},
    {10,6,5,2,0},
    {10,7,6,0,0}
};

void printmatrix()
{
    int i, j;

    for (i = 0; i < ROWS; i++) {
        for (j = 0; j < COLS; j++) {
            printf("%d ", data[i][j]); /* leaves a trailing space in each row */
        }
        printf("\n");
    }
}

int main()
{
    printmatrix();
    qsort(data, 5, sizeof(data[0]), (int (*)(const void *, const void *))rowcmp);
    printf("\n");
    printmatrix();
    return 0;
}

对于最灵活的解决方案,我会定义

struct row {
    size_t len;
    int *elems;
};

struct matrix {
    struct row *rows;
    size_t nrows;
};

并相应地更改代码。

注意:代码未经过彻底测试,请谨慎使用;)

答案 2 :(得分:0)

这是我在C ++中对矩阵重新排序的方法:

this.setState({
    count: currentCount
    counters: {
        isHidden: currentCount === 0
    }
});

答案 3 :(得分:-1)

您需要定义您使用的数据类型的指针数组,然后您可以重新排序矩阵。

例如你的矩阵是:arr [5] [10],你想在第3行之前打印第4行:

int *[5] arr2;
arr2[0] = &arr[0][0];
arr2[1] = &arr[1][0];
arr2[2] = &arr[2][0];
arr2[3] = &arr[4][0];
arr2[4] = &arr[3][0];

关于排序算法将如何工作,我建议在矩阵中的每个数组的开头放置一个标题,它将告诉你它有多少个元素(基本上每个数组的第一个元素可以是一个计数器之后你可以通过比较标题来排序字符串,如果它与第一个元素相比是相等的,依此类推。这可以在一个循环中完成,循环迭代的次数与数组中的元素一样多,当元素不相等时,就会脱离循环。 希望这有帮助。