问题
I have a temp2.dat
file that looks like this:
0.060493 1 0.5 1
1.596961 0 0.1 2
0.87758 1 0.3 1.5
0.165453 1 0 3
0.07085 1 0.3 4
0.125379 1 0.2 3
0.454202 1 0.2 2
0.373227 1 0.3 1
0.131486 1 0.3 3
0.867477 0 0.5 4
0.122609 0 0.8 9
Now I want to write the function in C
to sort these 4 columns in an increasing order but only based on the values of the first column. I tried modifying the following code but it failed:
struct data_t
{
double x;
int y;
double z;
double k;
};
int compare(const void *a, const void *b)
{
const struct data_t *m = a;
const struct data_t *n = b;
if(m->x == n->x)
return m->y > n->y;
return m->z > n->z;
return m->k > n->k;
return m->x > n->x;
}
Could someone please help me do this? The expected result should look like this:
0.060493 1 0.5 1
0.07085 1 0.3 4
0.122609 0 0.8 9
0.125379 1 0.2 3
0.131486 1 0.3 3
................
0.87758 1 0.3 1.5
1.596961 0 0.1 2
回答1:
Try this compare function
int compare(const void *a, const void *b)
{
const struct data_t *m = a;
const struct data_t *n = b;
if(m->x != n->x)
return (m->x > n->x) - (m->x < n->x);
if(m->y != n->y)
return m->y - n->y;
if(m->z != n->z)
return (m->z > n->z) - (m->z < n->z);
if(m->k != n->k)
return (m->k > n->k) - (m->x < n->k);
return 0;
}
This will compare the first column x
. If x
is the same in the two elements, it moves to the second column y
. If the second column is the same, it moves to the third column and so on.
We want the difference between the two values. Example, m->y - n->y
. The compare function should return an integer value 0, negative, or positive.
When comparing double
values, we cannot use m->x - n->x
, because the return value for compare
is int
. We use a comparison function instead.
Testing
struct data_t
{
double x;
int y;
double z;
double k;
};
int compare(const void *a, const void *b)
{
const struct data_t *m = a;
const struct data_t *n = b;
if(m->x != n->x)
return (m->x > n->x) ? 1 : -1;
if(m->y != n->y)
return m->y - n->y;
if(m->z != n->z)
return (m->z > n->z) ? 1 : -1;
if(m->k != n->k)
return (m->k > n->k) ? 1 : -1;
return 0;
}
int main(void)
{
struct data_t data[] =
{
{ 0.060493, 3, 0.4, 7 },//1st column is the same
{ 0.060493, 2, 0.5, 8 },
{ 0.060493, 1, 0.6, 9 },
{ 0.060493, 3, 0.3, 4 },//1st & 2nd columns are the same
{ 0.060493, 3, 0.2, 5 },
{ 0.060493, 3, 0.1, 6 },
{ 0.060493, 1, 0.5, 3 },//1st & 2nd & 3rd columns are the same
{ 0.060493, 1, 0.5, 2 },
{ 0.060493, 1, 0.5, 1 },
{ 0.122609, 0, 0.8, 9 },
{ 0.125379, 1, 0.2, 3 },
{ 0.131486, 1, 0.3, 3 },
};
int count = sizeof(data) / sizeof(data[0]);
qsort(data, count, sizeof(data[0]), compare);
for(int i = 0; i < count; i++)
{
printf("%.6f %d %.1f %.0f\n",
data[i].x, data[i].y, data[i].z, data[i].k);
}
return 0;
}
output:
0.060493 1 0.5 1 0.060493 1 0.5 2 0.060493 1 0.5 3 0.060493 1 0.6 9 0.060493 2 0.5 8 0.060493 3 0.1 6 0.060493 3 0.2 5 0.060493 3 0.3 4 0.060493 3 0.4 7 0.122609 0 0.8 9 0.125379 1 0.2 3 0.131486 1 0.3 3
回答2:
First off, in C if you want more than one statement inside any block, you have to surround it with {
and }
. So your last 3 return
statements would never be reached (the indentation does not matter for the compiler, only for humans).
Second, when you call return
, your code does not come back. So you could use nested if
s to compare the values in case they are the same in some of the columns. Something like:
int compare(const void *a, const void *b)
{
const struct data_t *m = a;
const struct data_t *n = b;
if(m->x == n->x) {
if (m->y == n->y) {
if (m->z == n->z) {
return m->k > n->k;
}
return m->z > n->z;
}
return m->y > n->y;
}
return m->x > n->x;
}
来源:https://stackoverflow.com/questions/49183054/sorting-2-d-array-based-on-the-first-column