繁体   English   中英

在数组子集上调用qsort

[英]Calling qsort on subset of array

我一直在寻找一种在C中对数组子集进行排序的方法,而不将元素移动到临时数组中,并将其复制回去。 我可能对qsort不太了解,但是我认为以下代码应该可以工作:

qsort(&my_struct_arr[1],3,sizeof(my_struct),my_struct_cmp);
//my_struct_arr is a 4 element array, where i want to sort from position 1 to 3
int my_struct_cmp(const void *a, const void *b)
{
    my_struct A=*(my_struct*)a, B=*(my_struct*)b;
    if(A.x-B.x < 0.01) return A.y-B.y;
    return A.x-B.x;
}
typedef struct foo
{
    float x, y;
} my_struct;

问题是,它不起作用。

更新1:好的,我知道我对这个问题并不完全清楚。 我将数组从位置1初始化为3,因此我有一个包含以下元素的数组:

{{ValueFromPreviousIteration.x,ValueFromPreviousIteration.y},{x1,y1},{x2,y2},{x3,y3}}

我的问题是,像上面这样调用的qsort将对整个数组进行排序,而我只想对它的最后3个元素进行排序。

您的比较功能不稳定。 它可以返回不同的结果,具体取决于传递结构的顺序。

请考虑以下结构值:

my_struct m = { -3.021, 30 };
my_struct n = { 3.010, 0 };    

int main(void)
{
    int comp1 = my_struct_cmp( &m, &n);
    int comp2 = my_struct_cmp( &n, &m);

    printf( "%d %d\n", comp1, comp2);

    return 0;
}

第一个比较表明m > n ,第二个比较表明n > m 这种行为会混淆qsort()

int my_struct_cmp返回int。

然后您将返回float 它将自动转换为int,并且可能为0

这就是为什么它不起作用的原因。

if(Ax-Bx < 0.01)是否正确? 您可能需要if(Ax-Bx < 0.0) 使用0.0而不是0.01

我认为您需要将比较功能修改为类似

int my_struct_cmp(const void* a, const void* b)
{
    const my_struct A = *(my_struct*)a, B = *(my_struct*)b;
    return fabs(A.x - B.x) >= 0.01 ? (A.x > B.x) - (A.x < B.x) : (A.y > B.y) - (A.y < B.y);
}

或(不太方便)

int my_struct_cmp(const void* a, const void* b)
{
    const my_struct A = *(my_struct*)a, B = *(my_struct*)b;
    return fabs(A.x - B.x) >= 0.01 ? copysign(1, A.x - B.x) : copysign(1, A.y - B.y);
}

否则,存在许多特定于平台的解决方案,用于在不执行比较的情况下确定浮点符号,这实际上并不是一件小事。

这应该更快一些:

int my_struct_cmp(const void* a, const void* b)
{
    const my_struct *A = (my_struct*)a, *B = (my_struct*)b;
    return fabs(A->x - B->x) >= 0.01 ? (A->x > B->x) - (A->x < B->x) : (A->y > B->y) - (A->y < B->y);
}

暂无
暂无

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

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