矢量中的移动元素没有按预期工作
moving elements in a vector is not working as expected
我正试图将每个元素的x值移动到向量的开始,以便所有元素的x值都在向量的前面,但它不工作,所以你能告诉我我做错了什么,请?
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typename Container::iterator it = find(c.begin(), c.end(), x);
if (it!=c.end()) {
c.insert(c.begin(), *it);
remove (it, c.end(), x);
}
}
int main()
{
int x=1;
vector <int> v{1,2,4,6,7,1,3,1,1,8,9};
move_x(v, x);
for(auto i:v)
cout<<v[i];
return 0;
}
当我运行它时,我得到了这个输出
411613848811
一旦插入到容器中,迭代器就不再有效了
c.insert(c.begin(), *it); // This invalidates 'it'
remove (it, c.end(), x); // oops! trying to use invalid iterator
使用std::rotate
提供了更好的选择,它不会使迭代器失效:
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typedef typename Container::iterator It;
It write_it = c.begin(), read_it = c.begin();
for (;;) {
It found_it = find(read_it, c.end(), x);
if (found_it==c.end()) break;
read_it = found_it;
++read_it;
std::rotate(write_it,found_it,read_it);
++write_it;
}
}
只要你处理的是像int这样简单的数据项,这是一个很好的方法:
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typename Container::reverse_iterator it = std::remove(c.rbegin(),c.rend(),x);
for (;it!=c.rend();++it) {
*it = x;
}
}
这是一个固定的实现,你在你的代码:
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typename Container::iterator it = find(c.begin(), c.end(), x);
if (it!=c.end()) {
c.erase(it);
c.insert(c.end(), x);
}
}
您的实现的一个问题是insert
在任何地方,但结束可能导致重新分配,无论如何将使插入位置后的任何内容无效。因此,根据定义,由于您在开头插入it
,因此将无效。
第二个问题是cout<<v[i];
,它实际上应该是cout<<i;
。
使用反向迭代器并移动所有x
的更好实现。这一个擦除,因为它去,并保持一个count
,然后count
插入完成时。在反向迭代器中使用erase有点棘手:
template <typename Container, typename Arg>
void move_all_x(Container& c, Arg x)
{
unsigned int count = 0 ;
for( typename Container::reverse_iterator it = c.rbegin() ; it != c.rend(); )
{
if( *it == x )
{
c.erase(--(it++).base() ) ;
++count ;
}
else
{
++it ;
}
}
for( unsigned int i = 0; i < count; ++i )
{
c.insert(c.begin(), x) ;
}
}
您可以使用std::partition,它将把范围内满足给定谓词的所有元素移到范围的开头,并返回一个指向第一个不满足谓词的元素的迭代器。
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
typename Container::iterator endrange =
std::partition(c.begin(), c.end(), [&x](Arg ele){ return ele == x; });
}
在这种情况下,我们没有使用返回值,但我认为它可能会很有用。
输出错误。应该有for (auto i:v) cout << i;
而不是v[i]
。使用正确的算法也可以看到垃圾
需要一个循环来处理所有匹配(或使用count和insert)。v
定义为list<int>
:
template <typename Container, typename Arg>
void move_x(Container& c, Arg x)
{
for (auto it = find(c.begin(), c.end(), x);
it != c.end();
it = find(it, c.end(), x)) {
c.insert(c.begin(), x);
it = c.erase(it);
}
}
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- QSqlquery prepare()和bindvalue()不工作
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 在为工作线程访问 lambda 中捕获的向量列表中的元素引用时,是否需要互斥锁?
- 试图使模板用于C 中结构的元素工作
- 为什么 vector::erase 不能在带有 const 的类元素上工作
- 我用于汇总数组元素的 c++ 代码无法正常工作
- C++二进制搜索无法正常工作-查找不在数组中的元素
- 排序C++,第一个元素不工作
- 难以理解某个函数的元素是如何工作的
- 多集是如何工作的,以及如何在多集中找到最小元素
- 如果元素不能为代码工作
- 自定义分配器- Microsoft std::map实现对相同的元素进行两次重新分配,GCC工作得很好
- 使用Qt,其中工作线程创建新的GUI元素
- 矢量中的移动元素没有按预期工作
- 快速排序不能在10k个元素下工作
- C++11 : map::lower_bound 在 Linux 中无法正常工作 2 个或更少的元素
- 这种从堆栈中删除元素的方法是如何工作的
- 向量在将其元素的引用推回到自身时是如何工作的