C ++:使用向量将特定数字移到后面
Posted
技术标签:
【中文标题】C ++:使用向量将特定数字移到后面【英文标题】:C++: Move a particular number to the back, using vector 【发布时间】:2020-07-20 22:43:20 【问题描述】:我有以下给定的向量:
vector<int> arr = 2,1,2,2,2,3,4,2;
目标是将目标编号一直移到后面。假设目标是 2,那么最终结果应该是这样的:
arr = 1,3,4,2,2,2,2,2
尝试
我的做法是循环遍历向量,然后如果找到2
,我会使用push_back
添加到末尾,同时擦除当前的2
。
在代码中,它看起来像这样:
vector<int> moveEndV1(vector<int> &arr, int toMove)
for (unsigned int i = 0; i < arr.size() ; i++)
if (arr[i] == toMove)
arr.push_back(arr[i]); // add to the end
arr.erase(arr.begin()+i); // erase current
return arr;
问题一旦我们删除了一个元素,循环计数器就出错了,因为它现在正在处理一个修改过的向量。 换句话说,假设我们从原始向量开始:
2,1,2,2,2,3,4,2
i = 0
的值为2
,因此我们将2
移到后面并删除了第一个2
。
所以我们有i = 0
:
1,2,2,2,3,4,2,2
这很好,但是当我们转到i = 1
时,i = 1
处的值不再像原来的数组那样是1
,而是2
。这是因为我们在i = 0
时删除了一个元素。所以,在i = 1
,在 push_back 和擦除之后,我们得到:
1,2,2,3,4,2,2,2
到目前为止一切顺利,但现在如果我们转到i = 2
,我们会得到:
1,2,3,4,2,2,2,2
i
会一直增加直到最后,最后我们在前面多了一个2
。
1,2,3,4,2,2,2,2
有没有办法解决这个问题?除了写一个单独的函数在前面搜索这个2
然后移到后面?
非常感谢任何帮助。
【问题讨论】:
【参考方案1】:您可以使用std::stable_partition
轻松做到这一点:
std::stable_partition(arr.begin(), arr.end(),
[toMove](int i) return i != toMove; );
【讨论】:
std::stable_partition
,可能。 OP 似乎想要保留 2
以外的元素的顺序【参考方案2】:
@cigien
解决方案很优雅;
但是稍微修改了您的代码,也可以使用;
void moveEndV1(std::vector<int> &arr, int toMove)
auto it = arr.begin();
for ( int i = 0; i < arr.size(); i++ )
if (*it == toMove )
int val = *it;
it = arr.erase( it );
arr.push_back( val );
else
++it;
【讨论】:
【参考方案3】:稳定的分区可以工作,但似乎有点过分(O(n log n)
时间,O(log n)
空间)。既然你知道你的目标号码,你不必立即推回它。相反,使用两个迭代器,src
和 dst
,类似于
auto dst = arr.begin();
for (auto src = arr.begin(); src != arr.end(); src++)
if (*src != toMove)
*dst++ = *src;
// At this point all non-target numbers are at the beginning of the
// array, and the order is preserved. Fill the rest with the target.
while (dst != arr.end())
*dst++ = toMove;
【讨论】:
以上是关于C ++:使用向量将特定数字移到后面的主要内容,如果未能解决你的问题,请参考以下文章