我想在保持向量按当前顺序的同时,从向量中消除重复元素。
下面我有一个拟议的实施方案。首先,这安全吗?
第二,是否有更好的方法来做到这一点,要么更有效率,要么从“使用C++算法而不是重新发明车轮”的角度。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
int main()
{
using namespace std;
std::vector<int> v= {1, 7, 2, 3, 8, 4, 5, 3, 2, 3, 2, 6, 2, 3, 2, 9, 10, 1, 2, 2, 1};
std::vector<int>::iterator finalEnd = v.end();
for (auto vIter = v.begin(); vIter != v.end(); ++vIter) {
for (auto nextvIter = vIter + 1; nextvIter != v.end(); ++nextProjIter) {
if (*vIter == *nextvIter)
finalEnd = std::remove(vIter, finalEnd, *nextvIter);
}
}
v.erase(finalEnd, v.end());
for(auto p : v)
cout << p << " ";
//Should return: 1 7 2 3 8 4 5 6 9 10
return EXIT_SUCCESS;
}发布于 2020-12-18 12:29:27
可以使用设置来跟踪重复项,使用隔断将重复项从唯一值中分割出来,同时保持项的顺序,这是可以实现的许多方法之一:
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
int main()
{
std::unordered_set<int> numSet;
std::vector<int> v= {1, 7, 2, 3, 8, 4, 5, 3, 2, 3, 2, 6, 2, 3, 2, 9, 10, 1, 2, 2, 1};
auto iter = std::stable_partition(v.begin(), v.end(), [&](int n)
{ bool ret = !numSet.count(n); numSet.insert(n); return ret; }); // returns true if the item has not been "seen"
v.erase(iter, v.end());
for(auto p : v)
std::cout << p << " ";
}输出:
1 7 2 3 8 4 5 6 9 10 如果没有看到项目,std::stable_partition将返回true,因此将其放置在分区点的左侧。一旦完成,就会返回到分区点的迭代器,我们使用这个迭代器从那个点到向量的末尾执行一次擦除。注意,lambda函数更新处理的每个项的unordered_set。
之所以使用std::stable_partition而不是std::remove_if,是因为std::remove_if不能保证按顺序处理项目。例如,实现可以先处理该数据中的第二个1,而不是第一个1。因此,为了安全起见,stable_partition不会删除元素,而只是将元素放置在正确的位置,准备在最后进行擦除。
发布于 2020-12-18 12:11:22
通过构造一个新的向量,您可以将这个向量初始化为非重复的.您可以为此使用find函数。我建议你搜索std ::查找
std::vector<int> v= {1, 7, 2, 3, 8, 4, 5, 3, 2, 3, 2, 6, 2, 3, 2, 9, 10, 1, 2, 2, 1};
std::vector<int> nonDuplicateVect;
for (int element : v)
if(std::find(nonDuplicateVect.begin(), nonDuplicateVect.end(), element) == nonDuplicateVect.end())
nonDuplicateVect.push_back(element);
for (int element : nonDuplicateVect)
std::cout << element << " ";
std::cout << "\n";https://stackoverflow.com/questions/65356524
复制相似问题