C++ 使用自定义比较器定义映射,其中值数据结构也具有自定义比较器

C++ 使用自定义比较器定义映射,其中值数据结构也具有自定义比较器,c++,c++11,data-structures,stl,C++,C++11,Data Structures,Stl,我想定义一个数据结构,如: struct node { int x_coordinate; int y_coordinate; // some variables }; map<node, priority_queue<node> > M; // or lets say map<node, set<node> > M 我面临的问题是,我不知道如何编写自定义比较器 另外,您认为是否可以根据与关键节点的距离对优先级队列进行

我想定义一个数据结构,如:

struct node {
    int x_coordinate;
    int y_coordinate;
    // some variables
};

map<node, priority_queue<node> > M;
// or lets say 
map<node, set<node> > M
我面临的问题是,我不知道如何编写自定义比较器

另外,您认为是否可以根据与关键节点的距离对优先级队列进行排序。例如,假设我的关键节点x_坐标=0,y_坐标=0,我想插入8,6,4,3,15,9,0,1

所以优先级队列应该是0,14,38,615,9

注:我在与人们讨论后使用了以下代码,但仍然给出了编译错误

struct Node {
    Node (int a, int b) {
        x = a;
        y = b;
    }
    int x, y;
};

struct cmp {
    Node node(0,0); // this node corresponds to the node that came from map key
    cmp(Node node) {
        this->node = node;
    }
    int getDistance (Node a, Node b) {
        return abs(a.x - b.x) + abs(a.y - b.y);
    }
    bool operator () (Node node1, Node node2) {
        return (getDistance(node, node1) < getDistance(node, node2));
    }

};

int main() {
    auto mapCmp = [&] (Node node1, Node node2){
        return node1.x < node2.x and (node1.x == node2.x and node1.y < node2.y);
    };
    map<Node, priority_queue<Node, vector<Node>, cmp(Node)>, decltype(mapCmp)> myMap(mapCmp);
    myMap[Node(0,0)].push(Node(2,4));
    myMap[Node(0,0)].push(Node(1,3));
    myMap[Node(0,1)].push(Node(2,4));
    myMap[Node(0,1)].push(Node(1,3));
    return 0;
}

错误快照:

我没有汇编上述内容。如果出现任何错误,则应进行简单的修复。我想我已经给了足够的密码来解除你的封锁。作为练习,尝试使用lambda而不是单独的比较器函数


我没有汇编上述内容。如果出现任何错误,则应进行简单的修复。我想我已经给了足够的密码来解除你的封锁。作为练习,尝试使用lambda而不是单独的比较器函数。

有趣的问题。基于映射自键值的后一部分优先级顺序表示真正的挑战

映射自定义键比较

从键比较到映射的三种基本方法是:


提供一个操作员感兴趣的问题。基于映射自键值的后一部分优先级顺序表示真正的挑战

映射自定义键比较

从键比较到映射的三种基本方法是:


提供一个类似这样的操作符:bool cmp node a,node b{return a.xstruct cmp { cmp(Node node) { this->node = node; } bool operator () (const Node& node1, const Node& node2) { return (getDistance(node, node1) < getDistance(node, node2)); } Node node; // this node corresponds to the node that came from map key };
std::map<Node, priority_queue<Node, vector<Node>, cmp(Node)>> myMap;
    cmp(Node node) { this->node = node; }
bool isLess = (a < b)
struct Node {
    Node(int a=0, int b=0)
        : x(a), y(b)
    {
    }

    int x, y;

    // called by default std::less
    bool operator <(const Node& rhs) const
    {
        return (x < rhs.x) || (!(rhs.x < x) && y < rhs.y);
    }
    
    // simple distance calculation between two points in 2D space.
    double distanceFrom(Node const& node) const
    {
        return std::sqrt(std::pow((x - node.x), 2.0) + std::pow((y - node.y), 2.0));
    }

    friend std::ostream& operator <<(std::ostream& os, Node const& node)
    {
        return os << '(' << node.x << ',' << node.y << ')';
    }
};
// instance-override type
struct NodePriority
{
    NodePriority() = default;

    NodePriority(Node node)
        : key(std::move(node))
    {
    }

    // compares distance to key of two nodes. We want these in
    // reverse order because smaller means closer means higher priority.
    bool operator()(const Node& lhs, const Node& rhs) const
    {
        return rhs.distanceFrom(key) < lhs.distanceFrom(key);
    }

private:
    Node key;
};

using NodeQueue = std::priority_queue<Node, std::deque<Node>, NodePriority>;
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <queue>
#include <map>
#include <random>

struct Node {
    Node(int a=0, int b=0)
        : x(a), y(b)
    {
    }

    int x, y;

    // called by default std::less
    bool operator <(const Node& rhs) const
    {
        return (x < rhs.x) || (!(rhs.x < x) && y < rhs.y);
    }

    // simple distance calculation between two points in 2D space.
    double distanceFrom(Node const& node) const
    {
        return std::sqrt(std::pow((x - node.x), 2.0) + std::pow((y - node.y), 2.0));
    }

    friend std::ostream& operator <<(std::ostream& os, Node const& node)
    {
        return os << '(' << node.x << ',' << node.y << ')';
    }
};

// instance-override type
struct NodePriority: public std::less<Node>
{
    NodePriority() = default;

    NodePriority(Node node)
        : key(std::move(node))
    {
    }

    // compares distance to key of two nodes. We want these in
    // reverse order because smaller means closer means higher priority.
    bool operator()(const Node& lhs, const Node& rhs) const
    {
        return rhs.distanceFrom(key) < lhs.distanceFrom(key);
    }

private:
    Node key;
};

using NodeQueue = std::priority_queue<Node, std::deque<Node>, NodePriority>;

int main()
{
    std::mt19937 rng{ 42 }; // replace with  { std::random_device{}() } for random sequencing;
    std::uniform_int_distribution<> dist(1, 9);

    std::map<Node, NodeQueue> myMap;

    // generate ten random points
    std::vector<Node> pts;
    for (int i = 0; i < 10; ++i)
        pts.emplace_back(Node(dist(rng), dist(rng)));

    for (int i = 0; i < 10; ++i)
    {
        Node node(i, i);
        myMap.insert(std::make_pair(node, NodeQueue(NodePriority(node))));
        for (auto const& pt : pts)
            myMap[node].emplace(pt);
    }

    // enumerate the map of nodes and their kids
    for (auto& pr : myMap)
    {
        std::cout << pr.first << " : {";
        if (!pr.second.empty())
        {
            std::cout << pr.second.top();
            pr.second.pop();
            while (!pr.second.empty())
            {
                std::cout << ',' << pr.second.top();
                pr.second.pop();
            }
        }
        std::cout << "}\n";
    }
}
(0,0) : {(3,1),(5,1),(3,5),(5,3),(5,4),(5,5),(1,9),(6,7),(5,8),(6,8)}
(1,1) : {(3,1),(5,1),(3,5),(5,3),(5,4),(5,5),(6,7),(1,9),(5,8),(6,8)}
(2,2) : {(3,1),(3,5),(5,1),(5,3),(5,4),(5,5),(6,7),(5,8),(1,9),(6,8)}
(3,3) : {(3,1),(3,5),(5,3),(5,4),(5,5),(5,1),(6,7),(5,8),(6,8),(1,9)}
(4,4) : {(5,4),(5,5),(3,5),(5,3),(5,1),(3,1),(6,7),(5,8),(6,8),(1,9)}
(5,5) : {(5,5),(5,4),(3,5),(5,3),(6,7),(5,8),(6,8),(5,1),(3,1),(1,9)}
(6,6) : {(6,7),(5,5),(6,8),(5,4),(5,8),(3,5),(5,3),(5,1),(1,9),(3,1)}
(7,7) : {(6,7),(6,8),(5,8),(5,5),(5,4),(3,5),(5,3),(1,9),(5,1),(3,1)}
(8,8) : {(6,8),(6,7),(5,8),(5,5),(5,4),(3,5),(5,3),(1,9),(5,1),(3,1)}
(9,9) : {(6,8),(6,7),(5,8),(5,5),(5,4),(3,5),(5,3),(1,9),(5,1),(3,1)}