繁体   English   中英

为qsort的结构编写比较函数?

[英]Writing a compare function for a structure for qsort?

我在C中为qsort函数编写比较函数时遇到了麻烦。这就是我目前所拥有的:

int cmpfunc(const void *a, const void *b) {
    return (*(Individual*)a->fitness - *(Individual*)b->fitness);
}

我知道比较函数是如何工作的,但我不明白如何在我的结构中引用一个名为Individual的整数值。 这是个人的结构。

typedef struct {
    PPM_IMAGE image;
    double fitness;
} Individual;

我想比较结构中的适应度值。

这部分

*(Individual*)a->fitness

是错的。 您尝试使用->访问fitness但同时使用*取消引用指针。 你不能两个都做!

这是两个解决方案。

解决方案A:使用*取消引用并使用访问fitness .

(*(Individual*)a).fitness

解决方案B:使用->访问fitness

((Individual*)a)->fitness

这两种解决方案还需要从void*Individual*

同样适用于变量b

如果您是C语言的初学者,我建议您避免在多个事情发生时使用紧凑语句。 而是将compact语句拆分为多个单独的语句。 这将使代码更容易理解和调试。 喜欢:

int cmpfunc (const void * a, const void * b){
    Individual* pA = a;
    Individual* pB = b;
    double fitnessA = pA->fitness;
    double fitnessB = pB->fitness;
    return fitnessA - fitnessB;
}

您无需担心性能问题。 编译器将优化代码,使其与单个语句代码一样高效。

那说 - 正如@chqrlie所说 - 注意比较代码是错误的!

该函数返回一个整数,但fitnessA - fitnessB是一个将被转换为整数的double。 所以0.1 - 0.0最终会返回0 - 这不是你想要的。

您可以从@chqrlie看到此答案https://stackoverflow.com/a/53466034/4386427以获取更多详细信息。

代码也可以像:

int cmpfunc (const void * a, const void * b){
    Individual* pA = a;
    Individual* pB = b;
    double fitnessA = pA->fitness;
    double fitnessB = pB->fitness;
    if (fitnessA > fitnessB) return 1;
    if (fitnessA < fitnessB) return -1;
    return 0;
}

假设您使用Individual结构数组调用qsort ,您应该将compare函数接收的参数转换为指向Individual结构的指针,最好是const Individual *以避免警告。

然后,您可以比较fitness成员并返回订购价值。 请注意,您不能只返回值的差异,因为这些可能是非整数,差异甚至可能超出int类型的范围。

这是一种经典的方法:

int cmpfunc(const void *a, const void *b) {
    const Individual *aa = a;
    const Individual *bb = b;
    /* return -1, 0 or 1 depending on the comparison results */
    return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM