Home > Net >  Sorting a matrix
Sorting a matrix

Time:12-22

Im trying to sort a matrix by the sum of its row's digits, from highest to lowest. I dont know if i explained that correctly so here's some photos explaining it.

enter image description here

This is what my code outputs. Basically, it asks you for m and n, which are the dimensions of the matrix. In this example it's a 3x4, 3 rows and 4 columns. Then, the matrix should be sorted by rows, by the sum of row's digits. Which means, instead of what's being outputted in the picture above, the correct result should be this:

enter image description here

I have no idea how to sort this from highest to lowest, i have been trying for hours to no avail. Here's my code:

#include <stdio.h>
#define N 30
    
void main(){
double a[N][N], s[N], p;
int i, j, m, n, max;

while(1){
    
    printf("\nm, n? ");
    scanf("%d%d", &m, &n);

    if(m <= 0 || m > N || n <=0 || n > N)
        break;

    for(i = 0; i < m; i  ){
        printf("-. row? ", i 1);
        for(j = 0; j < n; scanf("%lf", &a[i][j  ]));
    }
    
    for(i = 0; i < m; i  )
    for(s[i] = j = 0; j < n; s[i]  = a[i][j  ]);

    for(j = 0; j < n - 1; j  ){
        for(max = i, j = i 1; j < n; j  )
            if(s[j] > s[max])
                max = i;
                if(max != j){
                    p = s[j];
                    s[j] = s[max];
                    s[max] = p;
                    for(j = 0; j < m; j  ){
                        p = a[j][i];
                        a[j][i] = a[j][max];
                        a[j][max] = p;
                    }
                }
    }
    printf("New matrix: \n");

    for(i = 0; i < m; i  ){
        for(j = 0; j < n; printf("%8.2lf", a[i][j  ]));
        printf("\n");
    }
    for(j = 0; j < m; j  )
        printf("-------------");
    printf("\n");
    for(j = 0; j < m; printf("%8.2f \n", s[j  ]));
    printf("\n"); 
}
}

CodePudding user response:

You can sort the rows of the matrix from highest to lowest, using a simple bubble sort algorithm.Your code modified below:

int main() {

  double a[N][N], s[N], p;
  int i, j, m, n, max;

  while (1) {
    printf("\nm, n? ");
    scanf("%d%d", & m, & n);

    if (m <= 0 || m > N || n <= 0 || n > N)
      break;

    for (i = 0; i < m; i  ) {
      printf("-. row? ", i   1);
      for (j = 0; j < n; scanf("%lf", & a[i][j  ]));
    }

    for (i = 0; i < m; i  )
      for (s[i] = j = 0; j < n; s[i]  = a[i][j  ]);

    for (i = 0; i < m - 1; i  ) { // modified here
      for (j = i   1; j < m; j  ) { // modified here
        if (s[j] > s[i]) { // modified here
          p = s[i];
          s[i] = s[j];
          s[j] = p;
          for (int k = 0; k < n; k  ) {
            p = a[i][k];
            a[i][k] = a[j][k];
            a[j][k] = p;
          }
        }
      }
    }
    printf("New matrix: \n");

    for (i = 0; i < m; i  ) {
      for (j = 0; j < n; printf("%8.2lf", a[i][j  ]));
      printf("\n");
    }
    for (j = 0; j < m; j  )
      printf("-------------");
    printf("\n");
    for (j = 0; j < m; printf("%8.2f \n", s[j  ]));
    printf("\n");
  }

  return 0;
}

Here's how i modified your code to achieve that:

  • Initialize a loop variable i to 0.

  • In the outer loop, run the inner loop j from i 1 to m-1.

  • In the inner loop, compare the sum of the row i with the sum of row j. If the sum of row j is greater than the sum of row i, swap the rows using a temporary variable.

  • After the inner loop finishes, increment the value of i by 1. Repeat the outer loop until i becomes equal to m-1.

Output:

enter image description here

CodePudding user response:

You can just use qsort to let it handle the sorting and item swapping. Then you only need to write the code for comparing two rows with each other.

Given something like this:

int matrix[3][4] = 
{
  {1,2,3,4},
  {5,6,7,8},
  {9,1,2,3},
};

You'd call qsort as:

qsort(matrix, 3, sizeof(int[4]), compare);

The only complexity is implementing the comparison callback function. There's two things to consider there:

  • We've told qsort that we have an array of 3 items, each of type int[4]. So the void pointers it passes along to us will actually be pointers to type int[4]. That is: int(*)[4].
  • qsort sorts in ascending order by default, where the item considered "less" ends up first. So we need to tweak that to get the largest item first.

Example:

int compare (const void* obj1, const void* obj2)
{
  const int (*ptr1)[4] = obj1;
  const int (*ptr2)[4] = obj2;
  size_t sum1=0;
  size_t sum2=0;

  for(size_t i=0; i<4; i  )
  {
    sum1  = (*ptr1)[i];
    sum2  = (*ptr2)[i];
  }

  if(sum1 > sum2) // largest sum considered "less" for qsort
    return -1;
  else
    return 1;
  return 0;
}

sum1 < sum2 would have placed the smallest row first.


Full example:

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

int compare (const void* obj1, const void* obj2)
{
  const int (*ptr1)[4] = obj1;
  const int (*ptr2)[4] = obj2;
  size_t sum1=0;
  size_t sum2=0;
  
  for(size_t i=0; i<4; i  )
  {
    sum1  = (*ptr1)[i];
    sum2  = (*ptr2)[i];
  }

  if(sum1 > sum2) // largest sum considered "less" for qsort
    return -1;
  else
    return 1;
  return 0;
}

void print_matrix(size_t col, size_t row, int matrix[col][row])
{
  for(size_t i=0; i<col; i  )
  {
    for(size_t j=0; j<row; j  )
    {
      printf("%d,", matrix[i][j]);
    }
    puts("");
  }
}

int main (void)
{
  int matrix[3][4] = 
  {
    {1,2,3,4},
    {5,6,7,8},
    {9,1,2,3},
  };

  print_matrix(3,4,matrix);
  puts("");
  qsort(matrix, 3, sizeof(int[4]), compare);
  print_matrix(3,4,matrix);
}
  • Related