我有std::list
例如。使用整数:9 10 8 25 70 75 30 14 80
我想在10
元素之后移动小于some_position_number
的所有元素,例如。 = 5
。移动对象的初始顺序很重要,必须与移动后的初始顺序相同。
换句话说,最后需要接收some_position_number
及false
之后的true
元素
就像第一个例子一样:10 25 70 75 30 9 * 8 * 14 80
第二个首字母:9 3 8 25 70 75 30 14 80
第二个结果:10 25 70 75 30 9 * 3 * 8 14 80
第三个首字母:25 70 75 30 14 9 3 8 80
第三个结果:25 70 75 30 14 9 3 8 80
(开头已经是5)
4首字母:3 4 1 2 3 9 3 8 80
4结果:9 3 8 80 3 4 1 2 3
(类似这样)似乎some_position_number
必须用作阈值或80 3 4 1 2 3 9 3 8
也可以接受,但似乎需要检查end()和无限循环?
如何以最有效的方式做到这一点,可能没有额外的list
以避免不必要的对象创建和擦除?因为在真实的应用程序中,std::list
没有整数,而是对象。也许std :: splice?以某种方式选择需要移动的对象,而不是找到新的位置和std :: splice每个元素。
答案 0 :(得分:3)
It's ugly, but it works我相信它能正确处理所有迭代器失效情况:
#include <iostream>
#include <list>
using namespace std;
list<int> l;
// prototypes for various helpers of no consequence to the question
void init();
bool my_pred( list<int>::value_type val);
void dump_list( list<int> const& l);
typedef list<int>::iterator iter_t;
int main()
{
init();
dump_list(l);
// we want to remove elements that meet the predicate until
// there are `some_position_number` elements that didn't meet
// the predicate
int some_position_number = 5;
list<int> tmp_list;
iter_t i = l.begin();
for (int count = 0; count < some_position_number && i != l.end(); ) {
iter_t tmp(i);
++i;
if (my_pred(*tmp)) {
tmp_list.splice( tmp_list.end(), l, tmp); // remove an element
}
else {
++count;
}
}
// now i points at the position we want to insert the elements we removed:
l.splice( i, tmp_list);
dump_list(l);
}
bool my_pred( list<int>::value_type val)
{
return val < 10;
}
void init()
{
l.push_back(9);
l.push_back(10);
l.push_back(8);
l.push_back(25);
l.push_back(70);
l.push_back(75);
l.push_back(30);
l.push_back(14);
l.push_back(80);
}
void dump_list( list<int> const& l)
{
for (list<int>::const_iterator i = l.begin(); i != l.end(); ++i) {
cout << *i << " ";
}
cout << endl;
}
关键是:
i
必须先复制,然后在调用splice()
之前递增。调用splice()
后,原始i
(现在tmp
)将失效。