设置存储混乱

时间:2015-11-08 16:13:02

标签: c++ stl set

我已经宣布了一个结构:

struct data{
   vector<string> att;
   string ds;
};

现在设置一个存储来自多个数据元素的唯一数据

set<data> s;

基于不同的vector<string> attstring ds

怎么做?

2 个答案:

答案 0 :(得分:2)

如果不了解您希望如何比较结构,可以尝试以下方法:

struct data
{
    vector<string> att;
    string ds;

    friend bool operator < (const data& lhs, const data& rhs)
    {
        if (std::lexicographical_compare(lhs.att.begin(), lhs.att.end(), rhs.att.begin(), rhs.att.end()))
        {
            return true;
        }
        else if (std::lexicographical_compare(rhs.att.begin(), rhs.att.end(), lhs.att.begin(), lhs.att.end()))
        {
            return false;
        }
        else
        {
            return lhs.ds < rhs.ds;
        }
    }
};

我对此解决方案不满意,因为它执行两次词典比较,这是低效的。希望有人会提出更好的解决方案。

基本思路是,对于每个成员,比较左边&lt;对。如果为true,则返回true,否则比较右&lt;剩下。如果为true,则返回false。否则,继续下一个成员。

答案 1 :(得分:0)

注意:您可以详细了解我用来比较事物的技巧(std::tiein Implementing comparison operators via 'tuple' and 'tie', a good idea?

std::stringstd::vector已定义operator<for stringsfor vectors。因此,我们可以将它们与std::tie一起使用来创建临时std::tuple(它只使用对数据成员的引用,它不会创建任何副本,因此它非常有效)进行比较

选项1:提供operator<

std::set需要比较其对象,以便了解其独特之处以及如何对事物进行排序。它默认使用operator<(通过std::less)来执行此操作,因此如果您为您的类提供该运算符,它将使用它。像这样:

struct data{
   vector<string> att;
   string ds;

   operator<(const data& other) {
      // Be sure to #include <tuple> for std::tie
      return std::tie(att, ds) < std::tie(other.att, ds);

      // If you don't want to (or can't) use std::tie, you can do this:
      // return att < other.att || (att == other.att && ds < other.ds);
   }
};
std::set<data> my_set; // Now it works.

选项2:提供仿函数

这将使用Compare functor来比较两个data个对象(而不是operator<,因此我们不需要对其进行定义):

struct Compare {
   bool operator()(const data& left, const data& right) const {
      return std::tie(left.att, left.ds) < std::tie(right.att, right.ds);

      // Again, if you don't want to (or can't) use std::tie, you can do this:
      // return left.att < right.att || (left.att == right.att && left.ds < right.ds);
   }
};
std::set<data, Compare> my_set; // Now it works.