- #1
- 1,388
- 12
I have been trying to get qsort to sort the rows of a 2d array I read in from a data file, and I have not been having much success to get it to do what I want.
My array is a 4xarraysize array, where arraysize is the number of columns read in from a data file, with four entrees per row. I would like to sort the rows as a whole based on the first two columns: the first column should be sorted in ascending order, but contains many duplicate values, so the sorting should also end with the second row being in ascending order. No sorting within the rows should take place. For an example, if my array were
then upon sorting it should be
i.e., the entire row is moved, ordered based first on the first column and then based on the second column if two entrees of the first column are the same. No two rows will have the same pair of numbers in the first and second row, so sorting based on the third or fourth column is unnecessary.
My data is read in from a file and placed into an array array[4][arraysize], where the number of columns, arraysize, is determined by counting the number of columns in the input file.
The program calls qsort
and I have tried many different combinations of the second and third arguments ({arraysize, sizeof(double)}, {arraysize*4,sizeof(double)}, {arraysize, 2*sizeof(double)}, but no avail - none of them are giving the desired output and it is getting to the point where I think the error is simply that I don't really know quite how qsort is trying to work and I'm feeding it the wrong sizes and/or compare function.
My compare function is
The idea is that it compares the entrees of the elements it is given from the first column (which is why I though that the arguments to qsort should be arraysize, the size of the column, and 4*sizeof(double), so that it skips over the rest of the row and only looks at the first column), and if those are unequal, it sorts them, but if they are equal it looks at the entrees of the second column and sorts based on them.
I got this compare function (modified slightly) from a help post on the internet which seemed like the poster wanted to do the same thing, and supposedly it worked for them, but it's not doing what I want. Furthermore, I don't see how this sort of compare function will preserve the entire row. I feel like it doesn't, but I'm not sure how to fix that.
Any help will be appreciated!
My array is a 4xarraysize array, where arraysize is the number of columns read in from a data file, with four entrees per row. I would like to sort the rows as a whole based on the first two columns: the first column should be sorted in ascending order, but contains many duplicate values, so the sorting should also end with the second row being in ascending order. No sorting within the rows should take place. For an example, if my array were
Code:
0.002 365 7.333213e-03 3.385813e-02
0.019 689 3.272068e-02 2.226685e-01
0.008 259 5.767495e-02 1.144423e-01
0.002 2 6.409854e-04 -2.186733e-05
0.017 233 6.801931e-02 2.005469e-01
then upon sorting it should be
Code:
0.002 2 6.409854e-04 -2.186733e-05
0.002 365 7.333213e-03 3.385813e-02
0.008 259 5.767495e-02 1.144423e-01
0.017 233 6.801931e-02 2.005469e-01
0.019 689 3.272068e-02 2.226685e-01
i.e., the entire row is moved, ordered based first on the first column and then based on the second column if two entrees of the first column are the same. No two rows will have the same pair of numbers in the first and second row, so sorting based on the third or fourth column is unnecessary.
My data is read in from a file and placed into an array array[4][arraysize], where the number of columns, arraysize, is determined by counting the number of columns in the input file.
The program calls qsort
Code:
qsort(&array[0][0], arraysize, 4*sizeof(double), comparefun2);
and I have tried many different combinations of the second and third arguments ({arraysize, sizeof(double)}, {arraysize*4,sizeof(double)}, {arraysize, 2*sizeof(double)}, but no avail - none of them are giving the desired output and it is getting to the point where I think the error is simply that I don't really know quite how qsort is trying to work and I'm feeding it the wrong sizes and/or compare function.
My compare function is
Code:
int comparefun2(const void* a, const void* b) {
double* da = (double*)a;
double* db = (double*)b;
int diff1 = (da[0] > db[0]) - (da[0] < db[0]);
if (diff1 != 0) return diff1;
return (da[1] > db[1]) - (da[1] < db[1]);
}
The idea is that it compares the entrees of the elements it is given from the first column (which is why I though that the arguments to qsort should be arraysize, the size of the column, and 4*sizeof(double), so that it skips over the rest of the row and only looks at the first column), and if those are unequal, it sorts them, but if they are equal it looks at the entrees of the second column and sorts based on them.
I got this compare function (modified slightly) from a help post on the internet which seemed like the poster wanted to do the same thing, and supposedly it worked for them, but it's not doing what I want. Furthermore, I don't see how this sort of compare function will preserve the entire row. I feel like it doesn't, but I'm not sure how to fix that.
Any help will be appreciated!