如何(有效/快速)确定C中矢量(元素)的排名(不是C ++或使用非标准库)?例如,向量x=(0.25, 0.54, 0.38, 0.32, 0.49, 0.06, 0.41, 0.21, 0.98, 0.23)
的等级(ing)应为rank(x)=(4, 9, 6, 5, 8, 1, 7, 2, 10, 3)
。
顾名思义,“排名”给出了向量的每个元素相对于向量的所有其他元素的等级。因此rank(x[k])=l
表示k
中的x
元素是l
中所有元素中x
的最小元素(例如k=6
在上面的例子中,l
是1,即x的第6个元素是最小的)。请注意,这样的函数rank()
存在于其他几种编程语言中,但我还没有看到过C实现。我正在寻找的是一个纯C实现,它对整数或实数的向量尽可能快地工作。
答案 0 :(得分:5)
执行此操作的一种方法是将数据与索引配对,使用qsort
排序,并使用仅检查值并忽略索引的比较器,然后根据排序的索引分配排名。
这是malloc
临时数组对的实现,而不是使用自动存储。如果数据量足以超出堆栈,则更安全。
#include <stdio.h>
#include <stdlib.h>
struct rank_pair {
double val;
size_t ind;
};
int cmp_rank_pair(const void* a, const void* b) {
struct rank_pair *lhs = (struct rank_pair*)a;
struct rank_pair *rhs = (struct rank_pair*)b;
return lhs->val < rhs->val ? -1 : (lhs->val > rhs->val ? 1 : 0);
}
void rank(double a[], int r[], size_t n) {
struct rank_pair *tmp = malloc(n*sizeof(struct rank_pair));
for (int i = 0 ; i != n ; i++) {
tmp[i].val = a[i];
tmp[i].ind = i;
}
qsort(tmp, n, sizeof(struct rank_pair), cmp_rank_pair);
for (int i = 0 ; i != n ; i++) {
r[tmp[i].ind] = i+1;
}
free(tmp);
}
int main(void) {
const size_t N = 10;
double a[] = {0.25, 0.54, 0.38, 0.32, 0.49, 0.06, 0.41, 0.21, 0.98, 0.23};
int r[N];
rank(a, r, N);
for (int i = 0 ; i != N ; i++) {
printf("%d\n", r[i]);
}
return 0;
}