【问题标题】:How to solve comparing structs as key map c++如何解决比较结构作为键映射c ++
【发布时间】:2017-12-08 23:20:19
【问题描述】:

没有一个主题解决了我在 C++ 中将结构体作为键映射进行比较的问题。

结构代码如下:

struct XYZ{
  int x, y, z;
}

struct XYZComp{
  bool operator()(const XYZ& l, const XYZ& r)
  {
    return ((l.x==r.x)&&(l.y==r.y)&&(l.z==r.z));
  }
}

主要看起来像

int main()
{
  map<XYZ, int, XYZComp> m;
  m.insert(std::make_pair<XYZ,int>({1,2,3}, 1)); //ok

  map<XYZ, int, XYZComp>::iterator it = m.find({1,0,3});
  if(it!=m.end())
  {
    std::cout<<"Key exists in map"; 
  }
  else
  {
    m.insert(std::make_pair<XYZ,int>({1,0,3}, 1));
    //never come here 
    //compiler thinks key already exists in map
  }

return 0;
} 

我刚刚尝试不使用 XYZComparer,但它仍然无法正常工作。

struct XYZ{
  int x,y,z;
  bool operator==(const XYZ& xyz)
  {
    return (x=xyz.x) && (y=xyz.y) && (z=xyz.z);
  }
  bool operator<(const XYZ& xyz)
  {
    return (x>xyz.x) && (y>xyz.y) && (z>xyz.z);
  }
}

当我尝试地图中的现有项目时,如何解决比较这些结构 XYZ。

编辑:当至少一个数字正确时,编译器认为结构是相同的。

【问题讨论】:

  • "但还是不行。"没有帮助。我可以就这样离开它,让您找出原因(这同样有帮助),或者我可以解释为什么节省您查找它的时间和精力没有帮助......是的 - 如果它不起作用,说什么你得到了,你所期待的,这样人们就不必自己尝试解决了!

标签: c++ dictionary key stdmap


【解决方案1】:

std::map 使用&lt; 来订购商品。因此您的struct XYZComp 需要提供用户定义的operator &lt;

一个非常简单的解决方案是使用std::tie:

#include <tuple>
//..
struct XYZComp
{
    int x,y,z;
    bool operator < (const XYZComp& xyz)
    {
       return std::tie(x, y, z) < std::tie(xyz.x, xyz.y, xyz.z); 
    }
    //...
};

std::tie 为结构的元素引入了字典顺序。

你可以通过级联

struct XYZComp
{
    int x,y,z;
    bool operator < (const XYZComp& xyz)
    {
       if ( x < xyz.x )
         return true;
       if ( x == xyz.x &&  y < xyz.y )
         return true;
       if ( x == xyz.x && y == xyz.y )
           return z < xyz.z;
       return false;
   }
    //...
};

【讨论】:

  • 我必须让运算符
【解决方案2】:

std::setstd::map 的比较器应该作为 &lt;,而不是 ==。二叉搜索树不仅需要知道对象是否相等;它需要给它们一个顺序,因为数据结构是排序的。为您的对象重载 &lt; 运算符。

如果!comp(a, b) &amp;&amp; !comp(b, a),则认为对象相等。 (Source)

如果重载&lt;,则无需显式将比较器提供给容器类型,因为默认比较器是std::less,它包装了&lt; 运算符。

【讨论】:

    猜你喜欢
    • 2013-04-28
    • 2019-01-18
    • 1970-01-01
    • 2020-06-20
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 2012-05-11
    相关资源
    最近更新 更多