0

I want to sort the two-dimensional array of integers "d" according to the first column in decreasing order, using qsort(). However, I want each element of the first column to match the element that was in the second column in the same line on the beginning.

For example:

Array in the beginning:

column1: { 4, 5, 1, 3, 0}
column2: { 1, 2, 3, 4, 5}

and the result should be:

column1: { 5, 4, 3, 1, 0}
column2: { 2, 1, 4, 3, 5}

I have written the code for sorting an one-dimensional array, but I can't figure out how to do that for the two-dimensional one.

int main(){

    FILE *file_in, *file_out;

    file_in=fopen("file.in", "r");
        fscanf(file_in, "%d", &N);

    for( i = 1; i <= N; i = i + 1 ){
            fscanf(file_in, "%d", &a);

            fscanf(file_in, "%d", &b);

            fscanf(file_in, "%d", &c);

            d[i][1] = a+b+c;
            d[i][2] = a*b*c
    }
    fclose(file_in);

    int cmpfunc (const void * a, const void * b) {
        return ( *(int*)b - *(int*)a );
    }
    qsort(d, N, sizeof(int), cmpfunc);

    file_out=fopen("file.out","w");
    fprintf(file_out, "%d", M);
    for ( i=1; i<=N; i = i + 1){
        fprintf(file_out, "%d", d);
    }
    fclose(file_out);
    return 0;
}

Thank you in advance for your help.

Giannis D
  • 39
  • 1
  • 6
  • If the two columns are always treated a pair, one option could be to make it a one-dimensional array of `struct` containing two fields. – Arkku Jan 01 '19 at 00:44
  • 1
    Also, why do your arrays contain `float` when you treat the contents as `int` everywhere? Or, alternatively, why is everything else (including format strings) treating them as `int`? In particular, `a - a * (b/3000) - c * a /40` is very unlikely to give the results you expect when `a`, `b`, and `c` are `int`. – Arkku Jan 01 '19 at 00:45
  • 2
    Also, your range comparisons are impossible: `while (a < 1 && a > 1000000000)` continues as long as `a` is less than 1 _and at the same time_ greater than 1000000000… I'm sorry, but I'm tempted to say that you need to fix a lot of other stuff before `qsort` even becomes relevant. – Arkku Jan 01 '19 at 00:48
  • Make the size of your element be the size of a row. Not super efficient, but works. Alternatively, allocate an array of indices, sort them according to the contents of the first column. Then allocate another buffer the size of the original array and copy each row into the proper location. – Mad Physicist Jan 01 '19 at 00:59
  • @Arkku arrays were declared as float by mistake because I had tried something else earlier. You are also right about the `while`, I confused the data check conditions. Thank you for your advice. – Giannis D Jan 01 '19 at 01:33
  • the posted code does not compile! One of several reasons is: `apod1[k][2] = i k = k + 1;` is missing a trailing semicolon on the first statement. There are several other reasons. When compiling, enable the warnings, then fix those warnings. (for `gcc`, at a minimum use: `-Wall -Wextra -Wconversion -pedantic -std=gnu11` ) Note: other compilers use different options to perform the same thing – user3629249 Jan 01 '19 at 01:56
  • regarding: `file_in=fopen("file.in", "r");` always check (!=NULL) the returned value to assure the operation was successful. If not successful, then call `perror( fopen for input file failed" );` followed by: `exit( EXIT_FAILURE );` – user3629249 Jan 01 '19 at 01:59
  • because the function: `main()` is missing (at least) a final closing brace '}', the function: `cmpfunc()` is actually nested inside the `main()` function. While some compilers can be 'forced' to accept a nested function, that is not part of the C language specification. Please correct all the compiler problems and add an edit to your posted code with a valid C program. – user3629249 Jan 01 '19 at 02:04

1 Answers1

2

C doesn't allow the assignment of arrays. You could create an array of pointers, sort the pointers according to one of the arrays, the reorder the arrays according to the pointers using memcpy or a loop to move rows (the link below shows an efficient way to do this). (Using an array of indexes would require the compare function to be able to reference an array's elements only given the indexes.)

The second part of the answer in this thread shows the pointer method. For qsort(), the compare function input parameters would be pointer to pointer to (the first integer of a) row.

Sorting two arrays based on one with standard library (copy steps avoided)

An alternative would be to use structures, where each structure contains an array, since C does allow structures to be assigned.

rcgldr
  • 27,407
  • 3
  • 36
  • 61