我试图查找向量是否包含重复项(请不要提供检查重复项的算法。)我想到了这种奇怪的行为。向量1,2,3,1上的std :: unique应该使其1,2,3,1返回迭代器为1,但擦除迭代器返回到vector.end()时,我得到的向量大小与我是原始向量。这是描述上述行为的代码段(可从ideone获得)
vector<int> nums2 = {1,2,3,4};
vector<int> nums = {1,2,3,1};
cout << "nums1" << endl;
vector<int> a(nums.begin(), nums.end());
auto ip = unique(nums.begin(), nums.begin()+nums.size());
nums.resize( std::distance(nums.begin(),ip) );
cout << a.size() << " " << nums.size() << endl;
cout << "Nums2" << endl;
vector<int> a2(nums2.begin(), nums2.end());
auto ip2 = unique(nums2.begin(), nums2.begin()+nums2.size());
nums.resize( std::distance(nums2.begin(),ip2) );
cout << a2.size() << " " << nums2.size();
实际输出是
nums1
4 4
Nums2
4 4
但应该是
nums1
4 3
Nums2
4 4
答案 0 :(得分:5)
std::unique
仅删除连续的重复项。来自std::unique
上的cppreference.com:
从范围[first,last)中消除每组连续的等效元素中除第一个元素外的所有元素,并为该范围的新逻辑末尾返回一个end-the-end迭代器。 / p>
您的1不是连续的,因此不会被删除。这是预期的行为。快速解决方案是首先std::sort
您的范围。
答案 1 :(得分:2)
如果要删除重复的元素,同时又使它们按顺序出现,unique
不是您想要的。而是使用unordered_set
来跟踪您到目前为止所看到的元素。 (您可以使用remove_if
进行此操作,但是除非您熟悉lambda捕获语义,否则我不建议您这样做;只需在for循环中进行操作,然后阅读如何正确地从向量中删除元素在for循环中。)
答案 2 :(得分:1)
您误解了std :: unique的作用;它消除了所有连续元素之外的所有元素。也就是说,它不会删除相邻的重复项。 因此,要删除重复项,您需要确保所有重复项都位于彼此相邻的位置。使用std :: vector执行此操作的最简单方法是先应用std :: sort,然后再应用std :: unique。