【问题标题】:STL set find performanceSTL 设置查找性能
【发布时间】:2013-11-22 21:32:46
【问题描述】:

如何覆盖 MyNode 类中的 operator() 以便 set::find 可以使用,以及存储 MyNode* 的集合。然后我尝试在集合中找到指针,其数据字段与给定对象中的相同。下面的代码不像我预期的那样工作。我在运算符方法中设置了断点,但没有停止。

我知道我可以在 MyNode 类之外定义 find struct compare{},然后定义如下集合: 集集 这对我来说没问题。在这里,我想知道是否可以在 MyNode 类中定义比较。

我的代码是这样的:

class MyNode {
    std::string data;
public:
  MyNode();
MyNode(std::string str);
MyNode(const MyNode& orig);
virtual ~MyNode();

std::string getData();


bool operator<(const MyNode& node){
    return data<node.data;
}

bool operator<( const MyNode* node){
    return data<node->data;
}

};

void testset(){
MyNode* node1 = new MyNode("5S");

MyNode* node2 = new MyNode("AH");
MyNode* node3 = new MyNode("AH");
std::cout<<"  "<<node2<<std::endl;
std::set<MyNode*>  sets;
sets.insert(node1);
sets.insert(node2);

std::set<MyNode*>::iterator iter =sets.find(node3);  // I expected node2 can be found, but it does not.. 
if(iter != sets.end()){
    MyNode* no = *iter;
    std::cout<<"find it "<<no<<std::endl;   
}

}

另一个问题是我是否只定义了这样的集合:

           set<MyNode>  sets. 
           std::find(sets.begin(), sets.end(), findmethod("aa")) 

这个复杂度是 O(N) 还是 O(log N)?

【问题讨论】:

  • std::set 中搜索一个元素是 O(log N)。
  • @MarcClaesen 是吗?该标准要求它与设定的大小成对数。使用 algorithm std::find 而不是 container std::set&lt;T&gt;::find 确实是线性的,这可能就是您的意思。不确定。
  • @WhozCraig 我的意思是std::set&lt;T&gt;::find。我想我不够具体。
  • @MarcClaesen 是的,那个不是 O(n),而是 O(log(n)) 每个标准。泛型 std::find 将是 O(n) 仅仅是因为它通过前向迭代器进行枚举。如果搜索一个集合,使用std::set&lt;T&gt;::find 显然更好,它利用集合使用的任何内部数据结构(通常是 RB 树)来提供所需的对数复杂度。

标签: c++ stl find set


【解决方案1】:

至于第一个问题:std::set不关心operator()();它关心operator&lt;()

关于你的第二个问题:std::find 算法与std::set&lt;T&gt;::find 方法不同,是 O(n)。

【讨论】:

  • 我用 operator
  • 好吧,您存储的是set&lt;MyNode *&gt; 而不是set&lt;MyNode&gt;。如果您希望 set 以不同的方式比较 MyNode *,您将不得不提供自己的自定义比较器。
  • 在 MyNode 类之外定义一个名为 MyNodeCompare 的比较器,并将 init 设置为“set 集”有效.. 但我在这里想要的是寻求我可以定义覆盖的解决方案类 MyNode 中的 operator() 并声明 set 集,以便 sets.find() 可以工作..
  • @shijiexu 除非您实现自己的set 容器或以某种方式修改现有实现,否则您所要求的无法完成。正如@Frerich 已经指出的那样,std::set 不使用operator (),因此仅通过提供该运算符实际上无法获得所需的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
  • 2017-02-27
  • 2014-08-12
  • 2011-12-25
相关资源
最近更新 更多