【问题标题】:Custom comparison operator for custom struct in multiset C++多集 C++ 中自定义结构的自定义比较运算符
【发布时间】:2016-02-21 12:51:46
【问题描述】:

我有以下结构

 struct Node                                                         
{
    int x0,y0,g,h,f;
    int *Grid[N][N];
    Node* parent=NULL;
    Node(int x=0,int y=0,int G=0,Node* node=NULL)
    {
        x0=x;
        y0=y;
        g=G;
        parent=node;
    }
}

multiset的定义如下

multiset<Node*,GridLess>open_list;

Gridless是比较运算符的初始结构。

struct GridLess                                                                     
{
    bool operator()(const Node *a,const Node *b) const
    {
        for(i=0;i<N;i++)
        {
           for(j=0;j<N;j++)
           {
               if(*a->Grid[i][j]!=*b->Grid[i][j])
               {
                   return *a->Grid[i][j]<*b->Grid[i][j];
               }
           }
        }
        return false;
    }
};

我的基本需求是使用multiset::countmultiset::find在网格中的相同位置找到Node中的Node,由上述比较运算符完成。

现在我想要open_list 中的Node,它在网格中的相同位置具有相同的元素以及相同的Node::gNode::f

这是我尝试使用但失败了

struct GridLess                                                                    
{
    bool operator()(const Node *a,const Node *b) const
    {
        for(i=0;i<N;i++)
        {
           for(j=0;j<N;j++)
           {
               if(*a->Grid[i][j]!=*b->Grid[i][j])
               {
                   return *a->Grid[i][j]<*b->Grid[i][j]||(*a->Grid[i][j]==*b->Grid[i][j]&&a->g<b->g)||((*a->Grid[i][j] == *b->Grid[i][j])&&(a->g==b->g)&&a->f<b->f);
               }
           }
        }
        return false;
    }
};

open_list 中引入两个Nodes 具有相同的网格但不同的g 或f 仍然会导致count=2

我尝试使用以下内容仅检查 GridNode::g

return *a->Grid[i][j]<*b->Grid[i][j]||(*a->Grid[i][j]==*b->Grid[i][j]&&a->g<b->g);

即使这样也行不通。

我需要一个比较运算符来解决这个问题并解释它是如何工作的。

编辑

我想我不清楚 bool operator() 函数,就像我们写 return a&lt;b 时一样可以与问题一起解释这将非常有帮助。

【问题讨论】:

  • 这不可能是您的真实代码。至少缺少一个分号,并且Gridless 中的循环变量没有在任何地方声明。请发布真实代码
  • @StoryTeller 每个节点包含 NxN 个指向整数网格的 int 指针
  • @ChristianHackl 这是代码,我可能在某处跳过了分号,但声明了GridLess。注意:如果您要在您的机器上复制和运行,请将 GridLess 结构放在 multiset 声明上方。
  • 抱歉,语法突出显示让我失望(尽管您的命名约定不一致,所以您可能需要考虑一下)。
  • 我一定会调查的,谢谢

标签: c++ c++11 set comparison-operators multiset


【解决方案1】:

gf 成员的比较必须在循环之外。只要它在循环内,就不要比较 gf 成员,以防 Grid 成员相等。

struct GridLess                                                                     
{
    bool operator()(const Node *a,const Node *b) const
    {
        for(i=0;i<N;i++)
        {
           for(j=0;j<N;j++)
           {
               if(*a->Grid[i][j]!=*b->Grid[i][j])
               {
                   return *a->Grid[i][j]<*b->Grid[i][j];
               }
           }
        }
        return std::tie(a->g, a->f) < std::tie(b->g, b->f);
    }
};

【讨论】:

  • 好的,我该怎么做?我试着把它放在外面,结果相同:/
  • 添加了代码示例。当然,如果你有一个 nullptr a/bGrid
  • 非常感谢!我还对我的问题进行了编辑作为扩展名,您能否也解释一下? .
  • 关于您的后续问题:如果在所有其他情况下 a&lt;bfalse,则 less 运算符应返回 true
【解决方案2】:

您的比较运算符表现不佳。在循环中首先比较网格点,返回 pointA pointB。如果它们匹配,则比较其余的东西。

不知道为什么我的答案被切断了,但它与上面的完整答案相同。我觉得还不如开始一个标签...

【讨论】:

  • 是的,我知道这一点,但我不知道如何进行比较,我尝试了很多东西,如果你能详细说明如何使行为正确,那将会很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多