我已经得到了这段代码,但它不应该工作。我需要按降序对'val'数组进行虚拟排序,并将顺序存储在'order'数组中。
#include <stdio.h>
#define NUM_J_DIRS 4
#define FRAC_LEFT 0
#define FRAC_RIGHT 1
#define FRAC_FORWARD 2
#define FRAC_BACK 3
#define FIRST 0
#define SECOND 1
#define THIRD 2
#define FOURTH 3
struct iv
{
int index;
float value;
};
struct Fractions
{
int order[NUM_J_DIRS]; //this is where we store order of 'val'
float val[NUM_J_DIRS]; //once declared, this don't change
int enabled[NUM_J_DIRS]; //once declared, this don't change
};
int main ()
{
struct Fractions fractions;
struct iv iv[NUM_J_DIRS];
fractions.val[FRAC_LEFT] = 0.1;
fractions.val[FRAC_RIGHT] = 1.0;
fractions.val[FRAC_FORWARD] = 1.0;
fractions.val[FRAC_BACK] = 0.5;
// populate iv from val
for (int i = 0; i < NUM_J_DIRS; i++)
{
iv[i].index = i;
iv[i].value = fractions.val[i];
}
// sort kv by value
for (int i = 0; i < NUM_J_DIRS; i++)
{
for (int j = i + 1; j < NUM_J_DIRS; j++)
{
if (iv[i].value < iv[j].value)
{
struct iv temp = iv[i];
iv[i] = iv[j];
iv[j] = temp;
}
}
}
// set order
for (int i = 0; i < NUM_J_DIRS; i++)
{
fractions.order[iv[i].index] = i;
}
printf("order = %i, dir: %i, the value was: %fn",
FIRST, fractions.order[FIRST], fractions.val[fractions.order[FIRST]]);
printf("order = %i, dir: %i, the value was: %fn",
SECOND, fractions.order[SECOND], fractions.val[fractions.order[SECOND]]);
printf("order = %i, dir: %i, the value was: %fn",
THIRD, fractions.order[THIRD], fractions.val[fractions.order[THIRD]]);
printf("order = %i, dir: %i, the value was: %fn",
FOURTH, fractions.order[FOURTH], fractions.val[fractions.order[FOURTH]]);
return 0;
}
输出:
order = 0, dir: 3, the value was: 0.500000
order = 1, dir: 0, the value was: 0.100000
order = 2, dir: 1, the value was: 1.000000
order = 3, dir: 2, the value was: 1.000000
但是应该输出:
order = 0, dir: 1, the value was: 1.000000
order = 1, dir: 2, the value was: 1.000000
order = 2, dir: 3, the value was: 0.500000
order = 3, dir: 0, the value was: 0.100000
dir 1和dir 2的顺序是可以互换的,因为它们具有相同的值。相同值的方向顺序不重要。
上面的代码应该可以工作,但是没有。我花了无数的时间想知道为什么不可以。
对iv
进行排序后,元素按值降序排列,每个元素在fractions.val
数组中都有对应的索引。iv[0].index
给出最大元素的索引,iv[1].index
给出次大元素的索引,等等。因此,当您读取它时,您希望order
的第一个元素从iv
的第一个元素中取出index
,从第二个元素中取出第二个元素,以此类推。但这不是它的意思:
// set order for (int i = 0; i < NUM_J_DIRS; i++) { fractions.order[iv[i].index] = i; }
你已经颠倒了i
和iv[i].index
的意义。你真正需要的是
for (int i = 0; i < NUM_J_DIRS; i++)
{
fractions.order[i] = iv[i].index;
}
在我做了这个更改之后,你的程序的输出将为我按降序打印这些值。
声明这是你的比较函数:
int compareFunction(const void *p1, const void *p2, void *arg) {
struct Fractions* f = (struct Fractions*)arg;
int index1 = *(int*)p1;
int index2 = *(int*)p2;
if (f->val[index1] < f->val[index2]) {
return 1;
}
if (f->val[index1] > f->val[index2]) {
return -1;
}
return 0;
}
然后对"顺序"进行排序。基于"值"的现有顺序的数组。数组:
for (int i = 0; i < NUM_J_DIRS; i++) {
fractions.order[i] = i;
}
qsort_r(fractions.order, NUM_J_DIRS, sizeof(int), &fractions);
通过在源文件的顶部添加#include <stdlib.h>
来获得qsort_r
。