3

私がこのような構造を持っているとしましょう:

typedef struct MyStruct{
  char *string1;
  int number1, number2, number3;
  char string2[11], string3[9];
  char *string4;
  char *string5;
}MyStruct;

プログラムは、データをソートするフィールドを選択するようにユーザーに求めます。配列を効果的にソートする方法を考えるのに苦労しています。フィールドごとに個別の並べ替え関数を記述する必要はありますか? 2 つあれば十分な 8 つの関数を書くのは合理的に見えないため、別の方法があるはずです。

4

5 に答える 5

6

qsort()から見上げる<stdlib.h>。コンパレータ機能が必要です。さまざまな並べ替え順序に対して個別の比較関数を作成できますが、標準ライブラリqsort()を使用して並べ替えを行うこともできます。

例えば:

int ms_cmp_string1(const void *vp1, const void *vp2)
{
    const MyStruct *ms1 = vp1;
    const MyStruct *ms2 = vp2;

    int cmp = strcmp(ms1->string1, ms1->string2);
    if (cmp != 0)
        return cmp;
    else if (ms1->number1 < ms2->number1)
        return -1;
    else if (ms1->number1 > ms2->number1)
        return +1;
    //...other comparisons as required...
    else
        return 0;
}

これは、コンパレータの適切な概要です。これは でソートしてstring1から でソートしnumber1ます。さまざまなフィールドでソートするバリアントを作成するか、さまざまな可能なテストを選択した順序で適用するスキームを考案できます。qsort()しかし、基本的なアウトラインは非常にうまく機能し、キャストを必要とせずに渡すのに適しています.

于 2013-06-05T07:04:26.460 に答える
3

必要な関数が 2 つだけの場合は、8 つの関数を記述する必要はありません。独自の qsort 関数を作成し、メンバー オフセットを含む最後のパラメーターを比較関数に送信してから、比較関数でポインター + オフセットを正しい型にキャストします。

何かのようなもの:

int comp_int(const void *pa, const void *pb, size_t offset)
{
    const int *a = (const int *)((const char *)pa + offset);
    const int *b = (const int *)((const char *)pb + offset);

    return *a - *b;
}

int comp_string(const void *pa, const void *pb, size_t offset)
{
    const char *a = (const char *)pa + offset;
    const char *b = (const char *)pb + offset;

    return strcmp(a, b);
}

void swap(void *v[], int a, int b)
{
    void *temp;

    temp = v[a];
    v[a] = v[b];
    v[b] = temp;
}

void sort(void *v[], int left, int right, size_t offset, int (*comp)(const void *, const void *, size_t))
{
    int i, last;

    if (left >= right) return;
    swap(v, left, (left + right) / 2);
    last = left;
    for (i = left + 1; i <= right; i++) {
        if ((*comp)(v[i], v[left], offset) < 0)
            swap(v, ++last, i);
    }
    swap(v, left, last);
    sort(v, left, last - 1, offset, comp);
    sort(v, last + 1, right, offset, comp);
}

offsetofが役立ちます

于 2013-06-05T07:12:23.253 に答える