Попробуйте эту функцию сравнения
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;
}
Это сравнит первый столбец x
. Если x
совпадает в двух элементах, он перемещается во второй столбец y
. Если второй столбец такой же, он перемещается в третий столбец и так далее.
Нам нужна разница между двумя значениями. Пример, m->y - n->y
. Функция сравнения должна возвращать целочисленное значение 0, отрицательное или положительное.
При сравнении значений double
мы не можем использовать m->x - n->x
, потому что возвращаемое значение для compare
равно int
. Вместо этого мы используем функцию сравнения.
Тестирование
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;
}
выход:
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
person
Barmak Shemirani
schedule
08.03.2018
compare
функция странная. Пожалуйста, посмотрите несколько примеров, предположительно,qsort
, и будьте осторожны при тестировании значений с плавающей запятой на равенство. Опубликуйте минимальный, полный и проверяемый пример, демонстрирующий проблему. - person Weather Vane   schedule 09.03.2018return m->k > n->k;
иreturn m->x > n->x;
бесполезны, они никогда не будут достигнуты, вы можете вернуть только 1 объект из функции. И я настоятельно рекомендую добавить несколько скобок{ ... }
к вашему утверждениюif
, чтобы сделать его понятным, или, по крайней мере, изменить отступ. То, что у вас есть сейчас, вводит в заблуждение. - person yano   schedule 09.03.2018