【问题标题】:efficient comparator for an std::map with a struct key具有结构键的 std::map 的有效比较器
【发布时间】:2015-04-23 15:54:10
【问题描述】:

我有一个以下类型的结构,我计划将其用作地图中的键。 因此我写了一个如下的比较器。我想知道是否有更优雅但更有效的方法来做到这一点。
可能正在使用std::pair 或其他东西。

struct T 
{
  int a, b, c, d;

  bool operator< (const T& r) {
    if (a < r.a)
       return true
    else if (a == r.a)
       if (b < r.b)
          return true;
       else if (b == r.b)
            if (c < r.c) 
                return true;
            else if (c == r.c)
                if (d < r.d)
                   return true;
    return false;
  }
}

【问题讨论】:

    标签: c++ dictionary comparator predicate stdmap


    【解决方案1】:

    你可以使用 C++11 吗?如果是这样:

    struct T {
        int a, b, c, d;
    
        bool operator<(const T& rhs) const {
            return tied() < rhs.tied();
        }
    
    private:
        std::tuple<int, int, int, int> tied() const {
            return std::make_tuple(a, b, c, d);
        }
    };
    

    或者,我更喜欢 returning 在每个可能的机会避免容易出错的尴尬嵌套方法:

    bool operator<(const T& rhs) const {
        if (a != rhs.a) return a < rhs.a;
        if (b != rhs.b) return b < rhs.b;
        if (c != rhs.c) return c < rhs.c;
        return d < rhs.d;
    }
    

    【讨论】:

    • 很遗憾没有 c++11
    【解决方案2】:

    你可以使用...

    bool operator<(const T& r)
    {
        return a < r.a ||
               a == r.a && (b < r.b || 
                            b == r.b && (c < r.c || 
                                         c == r.c && d < r.d));
    }
    

    或者……

        return a != r.a ? a < r.a :
               b != r.b ? b < r.b :
               c != r.c ? c < r.c :
                          d < r.d;
    

    你说过你没有使用 C++11,Barry 很好地说明了元组方法,但供将来参考和其他感兴趣的人参考,并提供一些可重用的支持代码...

    bool less_by_pairs()
    {
        return false;
    }
    
    template <typename T, typename U, typename ...Args>
    bool less_by_pairs(const T& v1, const U& v2, Args... args)
    {
        return v1 != v2 ? v1 < v2 : less_by_pairs(args...);
    }
    

    ...您可以更轻松地实现此类运算符...

    bool operator<(const T& r)
    {
        return less_by_pairs(a, r.a, b, r.b, c, r.c, d, r.d);
    }
    

    您可以执行类似的操作,提供要比较的成员列表,但无论如何,它的符号实际上有点冗长。

    【讨论】:

      【解决方案3】:

      您可以使用另一个字段来存储密钥。这个键值可以通过一个公式生成,该公式以(a,b,c,d)为输入

      像这样:

      void hash()
      {
          key = (a ^ b ^ c ^ d);
      }
      

      因此,您只需要比较此密钥即可知道内容是否相同。

      【讨论】:

      • 这是std::map,我们需要将值按排序顺序排列。这不会区分 (0,0,0,1)(1,0,0,0)
      • @Barry 这是真的。我的错。
      猜你喜欢
      • 1970-01-01
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 1970-01-01
      相关资源
      最近更新 更多