3

構造のベクトル内のすべての構造のすべてのベクトルの最初の単語に基づいて構造のベクトルをアルファベット順に並べ替える最良の方法は何ですか?

struct sentence{
    vector<string> words;
};

vector<sentence> allSentences;

言い換えれば、words [0]に基づいてallSentencesをソートする方法は?


編集:私は次の解決策を使用しました:

bool cmp(const sentence& lhs, const sentence & rhs)
{
  return lhs.words[0] < rhs.words[0];
}

std::sort(allSentences.begin(), allSentences.end(), cmp);
4

3 に答える 3

6

適切な比較バイナリ関数を提供し、それをに渡しstd::sortます。例えば

bool cmp(const sentence& lhs, const sentence & rhs)
{
  return lhs.words[0] < rhs.words[0];
}

それから

std::sort(allSentences.begin(), allSentences.end(), cmp);

または、C ++ 11では、ラムダ無名関数を使用できます

std::sort(allSentences.begin(), allSentences.end(), 
          [](const sentence& lhs, const sentence & rhs) {
                     return lhs.words[0] < rhs.words[0];}
         );
于 2013-03-26T14:56:32.493 に答える
3

に渡すことができるいくつかの比較関数が必要ですstd::sort

bool compare(const sentence& a, const sentence& b)
{
  return a.words[0] < b.words[0];
}

ご覧のとおり、最初の単語の最初の単語が2番目の単語の最初の単語より「小さい」sentences場合は2つかかり、trueを返します。sentencesentence

次に、allSentences非常に簡単に並べ替えることができます。

std::sort(allSentences.begin(), allSentences.end(), compare);

もちろん、この比較を使用するということは、{"hello", "world"}とのような文{"hello", "friend"}が等しく比較されることを意味します。しかし、それはあなたが求めていたものです。

于 2013-03-26T14:56:04.940 に答える
3

一般に、検討する必要のある比較実装には、3つの異なるタイプのシナリオがあります。

  1. 常に意味のあるオブジェクトの比較。これは、オブジェクトを比較するシナリオから独立しています。次に:クラスに実装operator<します。この演算子は、2つのオブジェクトが比較されるたびに使用されます(<標準アルゴリズムが行うと)。(単一のシナリオの場合でも、以下の他の方法を使用してこの動作を「上書き」できます)。

    このために、次の関数を使用してクラスを拡張します。

    struct sentence{
        vector<string> words;
        bool operator<(const sentence &other) const {
            return this->words[0] < other.words[0];
        }
    };
    

    次に、他の引数なしで、文のベクトルに対して標準の並べ替えアルゴリズムを呼び出すだけです。

    std::sort(allSentences.begin(), allSentences.end());
    

    ただし、シナリオはこれが最善の方法ではないように思われます。最初の単語で比較することは、常に必要とは思わないことであり、場合によっては1つの場合に限られます。

  2. 一度だけ使用されるオブジェクトの比較。std::sortC ++ 11には、ラムダ関数(匿名の文字通りインライン関数)があり、このシナリオのように、それが使用されるアルゴリズム関数に直接渡すことができます。これは私のお気に入りの解決策です:

    // Sort lexicographical by first word
    std::sort(allSentences.begin(), allSentences.end(),
              [](const sentence& a, const sentence& b) {
        a.words[0] < b.words[0];
    });
    

    ラムダがないC++03では、3番目のソリューションを使用します。

  3. さまざまな再利用可能な比較方法のセット、おそらくパラメーター化された比較関数。例:最初の単語で比較する、長さで比較する、他の何かで比較する...この場合、比較関数を独立した関数として実装し、関数ポインターを使用するか、ファンクターとして実装します(パラメータ化されます)。また、この場合、変数に格納されているラムダがその役割を果たします。

    このメソッドには、比較メソッドに名前を付けて意味を与えるという利点があります。同じオブジェクトに対して異なる比較を使用するが、それらを再利用する場合、これは大きな利点です。

    // Lexicographical comparison by the first word only
    bool compareLexByFirstWord(const sentence& a, const sentence& b) {
        return a.words[0] < b.words[0];
    }
    
    // Lexicographical comparison by all words
    bool compareLex(const sentence& a, const sentence& b) {
        return a.words < b.words;
    }
    
    // Decide which behavior to use when actually using the comparison:
    std::sort(sentence.begin(), sentence.end(), compareLexByFirstWord);
    std::sort(sentence.begin(), sentence.end(), compareLex);
    
于 2013-03-26T15:03:16.537 に答える