简体   繁体   English

如何为std :: map实现std :: map的比较逻辑,该逻辑包含两个“ Pos”结构,每个结构均包含x和y坐标

[英]How to implement std::map::find comparison logic for a std::map containing two 'Pos' structs that each contain x and y coordinates

I am recreating Pac-Man and currently am implementing the ghost's path finding. 我正在重新创建《吃豆人》,目前正在实现幽灵的寻路。 I am using BFS. 我正在使用BFS。 I am having trouble implementing my 'Pos' class comparison logic so that my std::map::find works as intended. 我在实现“ Pos”类比较逻辑时遇到麻烦,因此我的std :: map :: find可以按预期工作。

'BFS' map 'BFS'地图

std::map<Pos, Pos> bfs;

'Pos' Struct Pos结构

struct Pos {
    int x_;
    int y_;

    bool operator==(const Pos &rhs) const { return (x_ == rhs.x_ && y_ == rhs.y_); };
    bool operator<(const Pos &rhs)  const { return (x_ < rhs.x_); };
};

The part of the function that uses std::map::find to check for unvisited XY positions. 函数的使用std :: map :: find的部分来检查未访问的XY位置。

if (bfs.find(neighbors.at(i)) == bfs.end()) {
    frontier.push(neighbors.at(i));
    bfs[neighbors.at(i)] = current;

    if (bfs[neighbors.at(i)] == end_tile) {
        quit = true;
    }
}

I used this website to learn how to use BFS for pathfinding: https://www.redblobgames.com/pathfinding/a-star/implementation.html#cpp-early-exit 我使用此网站来学习如何使用BFS进行寻路: https : //www.redblobgames.com/pathfinding/a-star/implementation.html#cpp-early-exit

I have tried multiple variations of <, and > for comparing x and or y, but it does not seem to work resulting in an empty map or a map with very few values - far from what is needed. 我已经尝试了<和>的多个变体来比较x和或y,但是它似乎无法正常工作,导致生成空的地图或地图中的值很少-远非所需。

Considering you have put enough thought on the algorithm you're using, in order to use Pos objects as keys in a std::map , you'll need to find the correct strict weak ordering criterion (the operator<) that meets your requirement. 考虑到您对正在使用的算法已作了充分的考虑,为了将Pos对象用作std::map键,您需要找到满足您要求的正确的严格弱排序准则(operator <) 。

bool operator<(const Pos& rhs) const {
    if(x_ < rhs.x_) return true;
    if(x_ > rhs.x_) return false;

    //x == coord.x
    if(y_ < rhs.y_) return true;
    if(y_ > rhs.y_) return false;

    //*this == pos
    return false;
}

You could also use something like std::tie (in C++11) which will first compare x, and then y: 您还可以使用std::tie类的东西(在C ++ 11中),它首先比较x,然后比较y:

bool operator<(const Pos& rhs) const
{
    // compare x_ to rhs.x_,
    // then y_ to rhs.y_
    return std::tie(x_,y_) < std::tie(rhs.x_, rhs.y_);
}

The comparison used for the map key must obey some rules. 用于映射键的比较必须遵守一些规则。 See documentation for more information: http://www.cplusplus.com/reference/map/map/ . 有关更多信息,请参见文档: http : //www.cplusplus.com/reference/map/map/

Essentially, in you case as your operator< only compare x value and not y value, any position with the same x would be considered equivalent so if you have multiple position with the same x but different y as the key, only one those will exist in the map. 本质上,在您的情况下,因为您的operator<仅比较x值而不是y值,具有相同x的任何位置都将被视为等效,因此,如果您拥有多个具有相同x但y与键不同的位置,则将仅存在一个在地图上。

As you are using bfs[neighbors.at(i)] = current; 当您使用bfs[neighbors.at(i)] = current; to update the value, you will get the last current value for a specific x instead of the last value for a specific {x, y}. 要更新该值,您将获得特定x的最后一个current值,而不是特定{x,y}的最后一个值。

You comparison should really be something like 您的比较应该确实像

 return x_ < rhs.x_ || x_ == rhs.x_ && y_ < rhs.y_;

Essentially when searching for the insertion position, the algorithm will only use operator< and not operator== . 本质上,当搜索插入位置时,该算法将仅使用operator<而不是operator==

Say that your map have the position { 3, 5 } and you want to insert { 3, 4 }. 假设您的地图位置为{3,5},并且您想插入{3,4}。

{ 3, 5 } < { 3, 4 } is false {3,5} <{3,4}为假

{ 3, 4 } < { 3, 5 } is false (since you only check x) {3,4} <{3,5}为假(因为您仅检查x)

Since both are false, they are considered equivalent and the existing item is updated (instead of adding a new item as desired). 由于两者都是错误的,因此它们被认为是等效的,并且现有项目已更新(而不是根据需要添加新项目)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM