【问题标题】:sorting a vector of structs [duplicate]对结构向量进行排序[重复]
【发布时间】:2011-06-21 00:44:36
【问题描述】:

我有一个vector<data> info,其中data 定义为:

struct data{
    string word;
    int number;
};

我需要按字串的长度对info 进行排序。有没有快速简单的方法?

【问题讨论】:

  • 如果您认为您的问题已解决,请将一个解决方案标记为已接受。
  • 对不起。我没有时间检查过去几个小时

标签: c++ sorting vector


【解决方案1】:

使用比较函数:

bool compareByLength(const data &a, const data &b)
{
    return a.word.size() < b.word.size();
}

然后在标头#include &lt;algorithm&gt;中使用std::sort

std::sort(info.begin(), info.end(), compareByLength);

【讨论】:

  • 如果我希望根据字段的字符串以字典方式对向量进行排序怎么办? (如果重要的话,我正在使用 C++11)。除了定义比较函数 /use lambda 而是使用 std::string 的积分 operator
【解决方案2】:

只要做一个比较函数/函子:

bool my_cmp(const data& a, const data& b)
{
    // smallest comes first
    return a.word.size() < b.word.size();
}

std::sort(info.begin(), info.end(), my_cmp);

或者在您的data 类中提供bool operator&lt;(const data&amp; a) const

struct data {
    string word;
    int number;

    bool operator<(const data& a) const
    {
        return word.size() < a.word.size();
    }
};

或者像 Fred 所说的非会员:

struct data {
    string word;
    int number;
};

bool operator<(const data& a, const data& b)
{
    return a.word.size() < b.word.size();
}

只需拨打std::sort():

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

【讨论】:

  • Op
  • 为什么operator&lt;() 应该是非会员?
  • @MuriloVasconcelos:所以隐式转换适用于左侧。
  • 恕我直言,您不应该使用运算符重载来包装不是立即直观的行为。在这种情况下,如果 data a 的字符串成员较短,那么说“小于”data b 并没有任何意义,所以我不会使用 operator&lt; 来表达这个想法。
  • 在这种情况下,我同意你的观点,这就是为什么我先写“功能方式”,然后再解释其他方式以供学习。
【解决方案3】:

是的:您可以使用自定义比较功能进行排序:

std::sort(info.begin(), info.end(), my_custom_comparison);

my_custom_comparison 需要是具有operator() 重载(函子)的函数或类,它接受两个data 对象并返回bool,指示第一个是否在第二个之前排序(即, first &lt; second)。或者,您可以为您的班级类型data 重载operator&lt;operator&lt;std::sort 使用的默认排序。

无论哪种方式,比较函数都必须产生 strict weak ordering 的元素。

【讨论】:

    【解决方案4】:

    正如其他人所提到的,您可以使用比较函数,但您也可以重载 less<T> 函子也可以工作:

    struct data {
        string word;
        int number;
        bool operator < (const data& rhs) const {
            return word.size() < rhs.word.size();
        }
    };
    

    那就是:

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

    编辑

    正如 James McNellis 指出的那样,sort 默认情况下实际上并不使用 less&lt;T&gt; 函子。但是,less&lt;T&gt; 函子也能正常工作的声明的其余部分仍然是正确的,这意味着如果你想将 struct datas 放入 std::mapstd::set 这仍然可以工作,但另一个提供比较功能的答案需要额外的代码才能使用。

    【讨论】:

    • 有趣的是,std::mapstd::set 默认使用 std::less&lt;T&gt;std::sort,其余排序函数默认使用 operator&lt;。如果您专门从事 std::less 的工作而不是 operator&lt; 所做的事情,您只会注意到差异。
    • 当我说“只有在...时你才会注意到不同”,我错了。如果您有一个指针容器,您也会注意到不同之处,例如std::vector&lt;int*&gt; v; v.insert(new int); v.insert(new int); std::sort(v.begin(), v.end());,因为如果您使用 &lt; 比较不相关的指针,则行为未定义。也就是说,我不知道为什么要按指针值而不是指向对象的值对指针容器进行排序。
    猜你喜欢
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多