0

クラス プロジェクトでは、文字列の配列を並べ替えます。各文字列には、次のように同じ数の列が含まれます。

カートライト ウェンディ 93
ウィリアムソン マーク 81
トンプソンマーク100
アンダーソン・ジョン 76
ターナー・デニス 56

プログラムは、ソートする列のコマンドライン引数を受け入れ、ソートされた文字列を変更せずに出力する必要があります。

strtok を使用して各文字列のコピーを列に分割し、次のように各行の構造体を作成したいと思います。

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}

私の問題は、qsort が引数として受け取る比較関数ポインターにあります。私の理解が正しければ、比較関数は、ソートされる項目への 2 つの const void ポインターを取り、int を返す必要があります。これは、構造体へのポインターを比較関数に渡すことができないことを意味します。これは、qsort がソートするものではないためです。比較関数に並べ替える列番号を渡すことはできません。これは、2 つの引数しか使用できないためです。特定の列に基づいてこれらの文字列をソートするには、どうすればこれを回避できますか?

編集:本当に必要な場合、並べ替えはqsortまたは自分のものに限定されます。選択肢を与えてください、私はqsortを選びます。:)

編集#2:コンセンサスは、列番号にグローバル変数を使用するか、単にqsortを使用して構造体の配列をソートしているようです。構造体を並べ替えて、それらのポインターを使用して元の文字列を出力することは考えていませんでした。それが私がすることだと思います。助けてくれてありがとう!

4

4 に答える 4

2

次のように構造体を渡すことができます。

struct line {
    char * line;
    char column_to_sort_on[MAX_COLUMN];
}
...

line*  Lines[max_lines]; // here you store the structs

int
cmp_lines( const void *elem1, const void *elem2 )
{
    line*  line1 = *(line**)elem1;
    line*  line2 = *(line**)elem2;
    // do the comparisons
}

qsort(Lines, max_lines, sizeof(line*), cmp_lines);
于 2009-09-19T19:48:53.883 に答える
2

qsort の使用に限定されていないと仮定すると、列番号を格納するファンクター オブジェクトで std::sort を使用できます。qsort を使用する必要がある場合は、列番号をグローバル変数に格納し、それを比較関数で使用するという手っ取り早い解決策があります。

于 2009-09-19T19:34:25.363 に答える
2

さまざまな比較関数。これらはすべて構造体全体を使用しますが、比較にはそれぞれ 1 つの列のみを使用します。

于 2009-09-19T19:36:41.083 に答える
1

C++ または C? あなたのタグに基づいて、C++ だと思います。STLの方法を試してみましょう。

std::sortの代わりに使用する必要がありqsortます。 std::sort関数ポインター (C の代替と比較して) だけでなく、関数として呼び出すことができる任意のオブジェクトを取ることができます。クラス インスタンスはoperator(). 次に、解決策は簡単です。構築時にさまざまな関数を作成する「ファンクター」クラスを作成します。ソート呼び出しは次のようになります。

std::sort(array, array+size, comparator(2 /* sort by column #2 */));

functor クラスは、いわゆる「クロージャー」を効果的に作成します。これは動的に作成された関数オブジェクトで、ローカル変数を持ちますが、この方法で作成された他の関数オブジェクトと共有しません。次のようになります。

class comparator{
  private: unsigned int field_n;
  public: comparator(unsigned int _field_n) : field_n(_field_n) {};
  public: int operator () (char const *  lhs, char const * rhs)
       { /* compare here fields with index field_n */ };
};

void ポインター比較の代わりに「関数」 (つまり、作成するクラス インスタンス) にはchar *パラメーターがあるため、型キャストを気にする必要はありません。

残念ながら、C では、グローバル変数を作成する以外の方法でこれを行うことはできません。

于 2009-09-19T19:46:37.057 に答える