c – 对std :: map的插入提示有什么位置限制吗?
我刚刚发现std :: map.insert可以接受迭代器作为其第一个参数作为插入过程的搜索提示,如map.insert(hintIterator,insertElement);.但是,提示元素有什么需求吗?是否需要在插入位置之前或之后?顺便提一下,提示迭代器位置对插入效率有多大的影响?
解决方法
它可以从begin()到end()的任何地方.如果您通过对应于理想插入位置的迭代器,您可以大大提高插入成本,以搜索正确的位置.
从SGI STL网站
要了解为什么会这样,请考虑正在应用的算法. std :: map有一些顺序排列的物品,为了找到正确的插入点,物品必须走过去,直到找到一个物品(“A”)必须位于新数据和下一个物品(“ B“)必须遵循.鉴于此位置提前可以消除搜索. 新数据必须在这两个项目之间,并更新它们之间的链接.至少(对于前向可迭代的容器),项目A必须被更新以指向新的数据,其随后指向B.如果包含的是可反向迭代的,则还必须更新B以指向新的数据. 应该如何指定位置?必须知道A或B的枯萎.正如Cubbi指出的那样,在alt.comp.lang.learn.c-cpp上讨论了2003年标准的提示应该是什么. SGI文档表明B是所需要的,而标准表明A.可能(给定std :: map有二次迭代器)没关系.但是,我建议,较低项目(A)的位置是最好的,因为您总是可以期待能够继续向前搜索. 更新:由于有经验的猜测是无效的,直到验证,这里是一个快速测试: #include <ctime> #include <map> #include <iostream> int main() { typedef std::map<unsigned int,unsigned int> map; const unsigned int k=100000; const unsigned int reps=10; // Avoid edge cases by padding either end map srcMap; { for(unsigned int i=0; i!=k;++i) { srcMap.insert(std::make_pair(i,i)); } unsigned int l=3*k; for(unsigned int i=2*k; i!=l;++i) { srcMap.insert(std::make_pair(i,i)); } } std::cout << "Hint is always the position of the preceding valuen"; for(unsigned int i=0; i!=reps;++i) { map testMap(srcMap); map::iterator p=testMap.lower_bound(k-1); unsigned int l=2*k; std::clock_t start = std::clock(); for(unsigned int i=k; i!=l;++i) { p=testMap.insert(p,std::make_pair(i,i)); } std::clock_t end = std::clock(); std::cout << static_cast<double>((end - start) ) << " "; } std::cout << std::endl; std::cout << "Hint is always the position of the following valuen"; for(unsigned int i=0; i!=reps;++i) { map testMap(srcMap); map::iterator p=testMap.lower_bound(2*k); unsigned int l=k-1; std::clock_t start = std::clock(); for(unsigned int i=2*k-1; i!=l;--i) { p=testMap.insert(p,i)); } std::clock_t end = std::clock(); std::cout << static_cast<double>((end - start) ) << " "; } std::cout << std::endl; std::cout << "Hint is always the start of the containern"; for(unsigned int i=0; i!=reps;++i) { map testMap(srcMap); unsigned int l=2*k; std::clock_t start = std::clock(); for(unsigned int i=k; i!=l;++i) { testMap.insert(testMap.begin(),i)); } std::clock_t end = std::clock(); std::cout << static_cast<double>((end - start)) << " "; } std::cout << std::endl; std::cout << "No hintn"; for(unsigned int i=0; i!=reps;++i) { map testMap(srcMap); unsigned int l=2*k; std::clock_t start = std::clock(); for(unsigned int i=k; i!=l;++i) { testMap.insert(std::make_pair(i,i)); } std::clock_t end = std::clock(); std::cout << static_cast<double>((end - start)) << " "; } std::cout << std::endl; return 0; } 在我的小上网本运行MinGW GCC 4.5我得到:
所以我会说暗示在任何一方给出了相同的结果,总是比没有提示更好.选择一个不好的提示位置(比如开始)比没有提示更糟糕. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |