0

I want to sort a matrix of number by rowwise(the average of row) and columnwise(the value of the element). I have written some code but there are some errors. What's wrong with my code?

#include <stdio.h>
#include <stdlib.h>
void print_array(int **matrix, int row, int col)
{
    int (*p)[col] = (int (*)[col])*matrix;
    for(int i = 0; i < row; ++i)
    {
        for(int j = 0; j < col; ++j)
        {
            printf("%d\t", p[i][j]);
        }
        printf("\n");
    }
}
int compare_avg(const void * a, const void * b)
{
    double avg_a = 0.0, avg_b = 0.0;
    const int *pa =  *(const int **)a;
    const int *pb =  *(const int **)b;
    for(int i = 0; i < 4; ++i)
    {
        avg_a += pa[i]/4.0;
        avg_b += pb[i]/4.0;
    }
    if(avg_a > avg_b) return 1;
    if(avg_a < avg_b) return -1;
    return 0;
}
int compare(const void* pa, const void* pb)
{
    const int a = *(const int*)pa;
    const int b = *(const int*)pb;
    if(a < b) return -1;
    if(a > b) return 1;
    return 0;
}
void sort_array(int **matrix, int row, int col)
{
    int (*p)[col] = (int (*)[col])*matrix;
    for(int i=0; i<row; ++i)
        qsort(p[i], col, sizeof(int), compare);
    print_array(matrix, row, col);
    printf("####################################\n");
    qsort(matrix, row, sizeof(matrix[0]), compare_avg);
    print_array(matrix, row, col);
}


int main(int argc, char* argv[])
{
    int array[5][4] = {
                {1,2,-1, -1},
                {3,2,-10,0},
                {4,2,1,0},
                {0,1,0,0},
        };
    int *p = &array[0][0];
    printf("%ld\n",sizeof(array)/sizeof(array[0]));
    printf("%ld\n",sizeof(array[0])/sizeof(int));
    print_array(&p, sizeof(array)/sizeof(array[0]), sizeof(array[0])/sizeof(int));
    printf("#########################################\n");
    sort_array(&p, sizeof(array)/sizeof(array[0]), sizeof(array[0])/sizeof(int));
    return 0;
} 

The output I needs is {{-10, 0, 3, 2}, {0, 0, 0, 1}, {-1, -1, 1, 2}, {0, 1, 2, 4}}.

RyanLi
  • 63
  • 8
  • What are the errors? Please include possible errors and what you've done to debug them in the question itself. – Ilja Everilä Apr 25 '17 at 07:24
  • the code can sort columnwise and have a output, but can't sort rowwiswe and output "segmentfault". – RyanLi Apr 25 '17 at 07:28
  • 1) `qsort(matrix, row, sizeof(matrix[0]), compare_avg);` --> `qsort(*matrix, row, sizeof(*p), compare_avg);` – BLUEPIXY Apr 25 '17 at 07:28
  • 2) `const int *pa = *(const int **)a; const int *pb = *(const int **)b;` --> `const int *pa = a; const int *pb = b;` – BLUEPIXY Apr 25 '17 at 07:29
  • All in all instead of passing a weirdly formed pointer to pointer to int that should end up pointing back to the first element of array of array of int (your `p`), why don't you pass that to begin with? `void sort_array(size_t rows, size_t cols, int matrix[rows][cols])`, remembering that `matrix` is actually a pointer to VLA such as `int (*matrix)[cols]`? – Ilja Everilä Apr 25 '17 at 07:35
  • I think you need to learn how to do an average .. `avg_a += pa[i]/4.0;` you should first add all of them, **then** divide by 4.0 – kaldoran Apr 25 '17 at 07:37
  • [DEMO](http://ideone.com/AU2aDf) – BLUEPIXY Apr 25 '17 at 07:38
  • @BLUEPIXY you're right. Thank you very much! Could you tell me why we need to change to those place? – RyanLi Apr 25 '17 at 07:43
  • Please think about it yourself. – BLUEPIXY Apr 25 '17 at 07:45
  • hint : The target of sorting is not an array of pointers. – BLUEPIXY Apr 25 '17 at 08:12
  • @BLUEPIXY that's very confusing. But a matrix(2D) is a array of pointer to it row. If I want sort it rowwise, didn't I sort an array of pointers? Why do you say the target is not an array of pointers? – RyanLi Apr 25 '17 at 08:36
  • 1
    A 2d array is not an array of pointers, but an array of arrays: http://stackoverflow.com/questions/7586702/is-2d-array-a-double-pointer – Ilja Everilä Apr 25 '17 at 08:37
  • @IljaEverilä Thank you. I think I know something. – RyanLi Apr 25 '17 at 09:05

0 Answers0