list<pair<int,int>> li{{5,6},{7,8},{9,10}};
for(auto it=li.rbegin();it!=li.rend();++it) {
cout << (*it).first << (*it).second << '\n';
li.erase(it);
}
错误:没有匹配函数来调用'std :: list&lt; std :: pair&lt; int,int&gt; &gt; :: erase(std :: reverse_iterator&lt; std :: _ List_iterator&lt; std :: pair&lt; int,int&gt;&gt;&gt;&amp;)'
li.erase(它);
如果li.erase(it)
被li.remove(*it)
替换,则代码正常。但是,所有的值都将被删除。并且算法变为O(n 2 ),而不是O(n),对吗?
答案 0 :(得分:2)
迭代时擦除是个坏主意。如果列表中不再显示it
,那么++it
会做什么?好问题!我不知道,但除非你不走运,否则它不是你想要的。如果程序有效,为什么不吉利?因为它没有,下次它可能会完全不同。
所以基本上所有基于循环的迭代和删除方法似乎都有效(li.remove(*it)
和li.erase( --(it.base()) )
实际上并没有。
通常我会调用erase-remove idiom来解决这个问题,但是如果你尝试使用C ++的内置工具,那么反向迭代器就会让它变得一团糟。此外,在这种情况下,remove_if的答案总是如此。
对于上面提出的问题,请不要尝试。而是打印li.back()
然后li.pop_back()
,直到列表为空。
while (!li.empty()) {
cout << li.back().first << li.back().second << '\n';
li.pop_back();
}
答案 1 :(得分:0)
您可以将condition ? value_if_true : value_if_false
替换为li.erase(it)
。
li.erase(it.base())
不允许std::list.erase
作为参数,因此您首先需要将reverse_iterator
转换为reverse_iterator
。
据我所知,你可以纠正O(n ^ 2)和O(n)分析。
修改强>
实际上,根据这个类似的答案:How to call erase with a reverse iterator
你应该做的是iterator