1

要素を一時配列に移動せずに 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つの要素のみをソートしたいということです。

4

4 に答える 4

1

比較関数が安定していません。構造体が渡される順序に応じて、異なる結果が返される可能性があります。

次の構造体の値を検討してください。

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、2 番目の比較は を示しますn > m。この種の動作は混乱を招きqsort()ます。

于 2012-11-30T09:32:11.223 に答える
0

正しいif(A.x-B.x < 0.01)ですか?あなたが望むかもしれませんif(A.x-B.x < 0.0)0.0の代わりに 使用0.01

于 2012-11-30T09:21:59.823 に答える
0

int my_struct_cmpint を返します。

そして、あなたは戻ってきてfloatいます。自動的に int に変換され、おそらく0.

それがうまくいかない理由です。

于 2012-11-30T09:18:18.560 に答える
0

比較関数を次のように変更する必要があると思います

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);
}

それ以外の場合、比較を実行せずに float の符号を決定するためのプラットフォーム固有のソリューションが多数存在しますが、これは実際には些細なことではありません。

そして、これは少し速くなるはずです:

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);
}
于 2012-11-30T09:50:00.237 に答える