【问题标题】:How do I use the std::find to find a set element with a struct member value?如何使用 std::find 查找具有结构成员值的集合元素?
【发布时间】:2020-10-21 02:33:01
【问题描述】:
struct Node{
    int id;
    float x;
    float y;
    float z;
    Node(int newId,float newX,float newY,float newZ){id=newId;x=newX;y=newY;z=newZ;}
    bool operator<(const Node& rhs)const {return id < rhs.id;}
};
set<Node> graph;
Node a(1,2,3,4);
Node b(2,1,2,3);
Node c(3,4,5,6);
graph.insert(a);
graph.insert(b);
graph.insert(c);

我想使用 find 函数查找具有特定 id 的 graph 元素。 像Node n = graph.find(3) 这样的东西会返回一个迭代器到 id 为 3、x 4、y 5、z 6 的元素。 目前 find 函数只接受一个初始化的 Node 作为参数。

【问题讨论】:

    标签: c++ struct set find std


    【解决方案1】:

    您尝试使用的是set&lt;Node&gt;::find() 而不是std::find()。您可以使用类似于std::find() - std::find_if() 的函数轻松地做您想做的事情:

    auto iter = std::find_if( graph.begin(), graph.end(), [](const Node& node){return node.id==3;});
    

    这个解决方案的问题是std::find()std::find_if() 具有O(n) 计算复杂度(其中n 是范围内的元素数量),而使用set&lt;Node&gt;::find() 只需要O(log(n)) 复杂度。如果您稍微改变您的设计(并且您至少使用 C++14),您就可以实现这一点。

    首先,结构节点使用非成员operator&lt;,并添加更多比较运算符:

    struct Node{
        int id;
        float x;
        float y;
        float z;
        Node(int newId,float newX,float newY,float newZ){id=newId;x=newX;y=newY;z=newZ;}
    };
    
    bool operator<(const Node& lhs, const Node& rhs)const {return lhs.id < rhs.id;}
    bool operator<(const Node& lhs, int rhs)const {return lhs.id < rhs;}
    bool operator<(int lhs, const Node& rhs)const {return lhs < rhs.id;}
    

    接下来,你需要使用一个带有透明比较器的集合:

    std::set<Node, std::less<>> graph;
    

    现在,您正在尝试的应该可以工作:

    auto iter = graph.find(3)
    

    【讨论】:

      【解决方案2】:

      如何使用 std::find 查找具有结构成员值的集合元素?

      目前 find 函数只接受一个初始化的 Node 作为参数。

      严格来说,std::find 完全没有这个要求。您可以传递与元素类型相当的任何类型的对象。也就是说,您可以使用std::find_if 而不是std::find

      请注意,std::find_if(如std::find)具有线性复杂度。如果您想要一个基于相关整数查找元素的数据结构是有效的,那么您将需要使用关联映射而不是集合。

      【讨论】:

      • std::findstd::find_if 总是具有线性复杂度 - 迭代器是否具有随机访问权无关紧要。
      • @Eugene 哦,是的。好点子。我在想std::distance。答案固定。
      猜你喜欢
      • 2023-03-30
      • 2020-08-24
      • 2011-09-26
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2020-03-29
      相关资源
      最近更新 更多