简体   繁体   English

std :: map迭代器和插入的行为

[英]Behavior of std::map iterators and insertions

As a simple start 作为一个简单的开始

Map<key,val> map1=//filled up in some way;
Map<key,val> map2;
map2.insert(map1.begin(),map1.end());

We know that map::insert is O(log(n)), with no hint provided. 我们知道map::insert是O(log(n)),没有提供提示。 Does this mean that the above runs in O(nlog(n)), or does it use the fact that map1 is already sorted and simply inserts at correct positions (incrementing the current iterator)? 这是否意味着上面的内容在O(nlog(n))中运行,或者它是否使用了map1已经排序并简单地插入正确位置(递增当前迭代器)的事实? Because map1 is already sorted, we should be able to do this in linear time. 因为map1已经排序,我们应该能够在线性时间内完成。 What about 关于什么

std::copy(map1.begin(),map1.end(),map2.end());

Does it insert every time in O(log(n)), or does it copy in O(1) to the respected position marked by incrementing the iterator? 它是每次都插入O(log(n)),还是在O(1)中复制到通过递增迭代器标记的受尊重位置?

A more illustrative example perhaps 或许更具说明性的例子

template<class InIter, class OutIter, class ResIter>
ResIter foo(InIter first, OutIter last, ResIter res){
   while(first!=last){
      res=*first;
      ++first;
      ++res;
   }
return res;
}

Does this run in O(n), or O(nlog(n)), when we are dealing with a map iterator? 当我们处理地图迭代器时,这是在O(n)还是O(nlog(n))中运行? Are insertions O(log(n)), or are they O(1), because we specify position, ie *res=*first ? 是插入O(log(n)),还是O(1),因为我们指定位置,即*res=*first

Edit for clarity: 为清晰起见编辑:

Does 是否

*res=*first

behave as 表现得像

map2.insert(res,*first)

meaning, inserting into map2, using the iterator res pointing to the correct position as a hint, making it O(1), or does it perform the regular O(log(n)) insertion? 意思是,插入到map2中,使用指向正确位置的迭代器res作为提示,使其成为O(1),还是执行常规的O(log(n))插入?

After a quick read on standard, there is no requirement on the complexity of void insert(InputIterator first, InputIterator last); 在快速阅读标准之后,对void insert(InputIterator first, InputIterator last);的复杂性没有要求void insert(InputIterator first, InputIterator last); . So a lazy implementation is allowed to have a O(n log(n)) complexity, even it is likely that it will be linear if map1 is empty due to what follows. 因此,允许延迟实现具有O(n log(n))复杂度,即使由于以下内容而map1为空,它也可能是线性的。

Because the standard does require a linear complexity for the constructor if the input range is sorted, so this is required to be O(n): 因为如果输入范围是排序的,标准确实需要构造函数的线性复杂性,所以这需要是O(n):

Map<key,val> map1=//filled up in some way;
Map<key,val> map2(map1.begin(),map1.end()); // complexity in O(n)

For the second part of your question, as you want to give a hint on where the element should be inserted, the correct way would be: 对于问题的第二部分,因为您想要提示元素应该插入的位置,正确的方法是:

template<class InIter, class OutIter, class ResIter>
ResIter foo(InIter first, OutIter last, ResIter res){
   while(first!=last){
      emplace_hint(res, *first);
      ++first;
      ++res;
   }
return res;
}

Unfortunately, the standard places no requirement either on the complexity of emplace or emplace_hint . 不幸的是,标准的地方上的复杂性没有要求任何emplaceemplace_hint

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

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