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 中,您可以使用 lambda 匿名函数

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

Generally, there are three different types of scenarios for comparison implementations you should consider.

  1. A comparison of your object that makes always sense. It's independent from the scenario in which you want to compare objects. Then: Implement operator< for your class. This operator is used whenever two objects are compared (with <, which the standard algorithms do). (For single scenarios, you can still "overwrite" this behavior using the other methods below).

    For this, extend your class with the following function:

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

    Then, just call the standard sorting algorithm on your vector of sentences without other arguments:

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

    However, your scenario doesn't sound like this is the best method, since comparing by the first word is something you don't want to have always, maybe only in one case.

  2. A comparison of your object which will be used only once. In C++11, you have lambda functions (anonymous, literally inlined functions), which can be passed directly to the algorithm function in which it will be used, like std::sort in this scenario. This is my favorite solution:

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

    In C++03, where you don't have lambdas, use to the 3rd solution:

  3. A set of different, re-usable comparison methods, maybe a parameterized comparison function. Examples are: Compare by the first word, compare by length, compare by something else... In this case, implement the comparison function(s) either as free-standing functions and use function pointers, or implement them as functors (which can be parameterized). Also, lambdas stored in variables do the job in this case.

    This method has the advantage to name the comparison methods, giving them a meaning. If you use different comparisons for the same object, but re-use them, this is a huge advantage:

    // 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 回答
3

您需要一些可以传递给的比较函数std::sort

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

如您所见,如果第一个单词的第一个单词“小于”第二个单词的第一个单词,则它需要两个sentences并返回 true 。sentencesentence

allSentences然后你可以很容易地排序:

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

当然,使用这种比较意味着句子 like{"hello", "world"}{"hello", "friend"}will 比较相等。但这就是你所要求的。

于 2013-03-26T14:56:04.940 回答