【问题标题】:How to sort a vector of structs based on a vector<string> within the vector to be sorted?如何根据要排序的向量中的 vector<string> 对结构向量进行排序?
【发布时间】:2013-03-16 10:23:58
【问题描述】:

根据结构向量中所有结构的每个向量中的第一个单词按字母顺序对结构向量进行排序的最佳方法是什么?

struct sentence{
    vector<string> words;
};

vector<sentence> allSentences;

也就是说,如何根据 words[0] 对所有句子进行排序?


编辑:我使用了以下解决方案:

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

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

【问题讨论】:

  • 感谢您的精彩回答。也许有人可以解释为什么这不起作用:return lhs.wordCombinated[0].compare(rhs.wordCombinated[0]);

标签: c++ sorting vector struct


【解决方案1】:

提供一个合适的比较二进制函数并将其传递给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];}
         );

【讨论】:

    【解决方案2】:

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

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

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

    那么你就可以很轻松的对allSentences进行排序了:

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

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

    【讨论】:

      【解决方案3】:

      一般来说,您应该考虑三种不同类型的方案来进行比较实施。

      1. 始终有意义的对象比较。它独立于您想要比较对象的场景。然后:为您的班级实施operator&lt;。每当比较两个对象时都会使用此运算符(使用&lt;,标准算法会这样做)。 (对于单一场景,您仍然可以使用以下其他方法“覆盖”此行为)。

        为此,请使用以下函数扩展您的类:

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

        然后,只需在不带其他参数的句子向量上调用标准排序算法:

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

        但是,您的场景听起来并不是最好的方法,因为您不希望通过第一个单词进行比较总是,也许只有在一种情况下。 p>

      2. 您的对象的比较只使用一次。在 C++11 中,您有 lambda 函数(匿名,字面意思是内联函数),可以将其直接传递给将在其中使用它的算法函数,如本场景中的 std::sort。这是我最喜欢的解决方案:

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

        在没有 lambda 的 C++03 中,使用第三种解决方案:

      3. 一组不同的、可重复使用的比较方法,可能是参数化比较函数。示例是:按第一个字比较、按长度比较、按其他内容进行比较……在这种情况下,将比较函数实现为独立函数并使用函数指针,或者将它们实现为函子(可以参数化)。此外,在这种情况下,存储在变量中的 lambda 也可以完成这项工作。

        这种方法的优点是命名比较方法,赋予它们含义。如果您对同一个对象使用不同的比较,但重复使用它们,这是一个巨大的优势:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-12
        • 1970-01-01
        • 2021-11-04
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多