c++ 检查std::vector是否存在重复项

bvjxkvbb  于 2023-10-21  发布在  其他
关注(0)|答案(8)|浏览(212)

我想检查一个整数向量是否有任何重复,如果有,就必须返回true。所以我试着这样做:

  1. vector<int> uGuess = {1,2,3,3,4,5}
  2. vector<int> a = uGuess;
  3. sort(a.begin(), a.end());
  4. bool d = unique(a.begin(), a.end());

这将不起作用,因为unqiue不能被分配为bool值。我该如何着手呢?如果我写一个for循环来执行相同的操作,我应该怎么做?

e5nszbig

e5nszbig1#

你要找的算法是std::adjacent_find

  1. // The container must be sorted!
  2. const std::vector<int> sortedVector = {1,2,3,3,4,5};
  3. const bool hasDuplicates = std::adjacent_find(sortedVector.begin(), sortedVector.end()) != sortedVector.end();

std::unique不同,std::adjacent_find不会修改容器。
作为奖励,std::adjacent_find返回重复“对”中第一个元素的迭代器:

  1. const auto duplicate = std::adjacent_find(sortedVector.begin(), sortedVector.end());
  2. if (duplicate != sortedVector.end())
  3. std::cout << "Duplicate element = " << *duplicate << "\n";
gopyfrb3

gopyfrb32#

你应该使用set

  1. set<int> s(a.begin(), a.end());
  2. return s.size() != a.size();
ergxz8rk

ergxz8rk3#

在google搜索std::unique时,我找到了这个页面std::unique。我看了看它做了什么:
从[first,last]范围内的每个连续等效元素组中删除除第一个元素之外的所有元素
所以它看起来像你想要的-删除重复。
然后我看了看它返回的内容...
..
所以std::unique的结果是一个序列,它不一定与整个vector相同。
如果没有删除任何内容,则返回值将是vector的结尾。
因此,您需要:

  1. vector<int>::iterator it = std::unique(a.begin(), a.end());
  2. bool wasUnique = (it == a.end());

对于C++11:

  1. auto it = std::unique(a.begin(), a.end());
  2. bool wasUnique = (it == a.end());

最后,为了使唯一函数正常工作,需要对vector进行排序,因此完整的代码如下:

  1. sort(a.begin(), a.end());
  2. auto it = std::unique(a.begin(), a.end());
  3. bool wasUnique = (it == a.end());
展开查看全部
lymgl2op

lymgl2op4#

如果有人被迫写自己的算法:

  1. bool hasDuplicates(const std::vector<int>& arr) {
  2. for (std::size_t i = 0; i < arr.size(); ++i) {
  3. for (std::size_t j = i + 1; j < arr.size(); ++j) {
  4. if (arr[i] == arr[j])
  5. return true;
  6. }
  7. }
  8. return false;
  9. }

但是在真实的代码中,你应该使用已经存在的东西,在标准库中。

pw9qyyiw

pw9qyyiw5#

如果向量还没有排序,则对它进行排序,然后使用std::unique(),如下所示:

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. int main() {
  5. std::vector<int> v = {3, 1, 3, 4, 5};
  6. sort(v.begin(), v.end());
  7. auto it = std::unique(v.begin(), v.end());
  8. std::cout << ((it == v.end()) ? "Unique\n" : "Duplicate(s)\n");
  9. return 0;
  10. }

输出量:
重复

nnt7mjpx

nnt7mjpx6#

到目前为止,所有这些解决方案要么修改容器,要么具有O(n²)的复杂度。你可以把std::map放到更好的用途:

  1. #include <algorithm>
  2. #include <iterator>
  3. #include <map>
  4. template <typename Iterator>
  5. bool has_duplicates( Iterator first, Iterator last )
  6. {
  7. std::map <typename std::iterator_traits <Iterator> ::value_type, std::size_t> histogram;
  8. while (first != last)
  9. if (++histogram[ *first++ ] > 1)
  10. return true;
  11. return false;
  12. }
  13. #include <iostream>
  14. #include <vector>
  15. int main()
  16. {
  17. using std::begin;
  18. using std::end;
  19. int a[] = { 2, 3, 5, 7, 11 };
  20. int b[] = { 2, 3, 5, 5, 7 };
  21. std::vector <int> c( begin(a), end(a) );
  22. std::vector <int> d( begin(b), end(b) );
  23. std::cout << std::boolalpha;
  24. std::cout << "a has duplicates false : " << has_duplicates( begin(a), end(a) ) << "\n";
  25. std::cout << "b has duplicates true : " << has_duplicates( begin(b), end(b) ) << "\n";
  26. std::cout << "c has duplicates false : " << has_duplicates( begin(c), end(c) ) << "\n";
  27. std::cout << "d has duplicates true : " << has_duplicates( begin(d), end(d) ) << "\n";
  28. }
展开查看全部
8ulbf1ek

8ulbf1ek7#

如果你的vector很小,比如< 32个对象,或者如果由于缺少移动或复制构造函数/赋值而复制和排序对象是昂贵的或不可能的,那么直接的O(n^2)比较所有的东西都是其他的算法。
以下是我的解决方案:

  1. template <typename Iterator>
  2. bool has_duplicates( Iterator first, Iterator end ) {
  3. for (auto i = first; i != end; ++i) {
  4. for (auto j = first; i != j; ++j) {
  5. if (*i == *j) return true;
  6. }
  7. }
  8. return false;
  9. }
  10. template <typename Container>
  11. bool has_duplicates(const Container &v) {
  12. for (const auto & i : v) {
  13. for (const auto & j : v) {
  14. if (&i == &j) break;
  15. if (i == j) return true;
  16. }
  17. }
  18. return false;
  19. }
展开查看全部
iyfamqjs

iyfamqjs8#

如果你有一个更复杂的向量,想知道哪个值是重复的,你可以这样做:

  1. #include <vector>
  2. #include <unordered_set>
  3. #include <string>
  4. template <typename InputContainer_t, typename GetCompareValueLambda_t>
  5. bool HasDuplicates(const InputContainer_t& container, GetCompareValueLambda_t compare)
  6. {
  7. using CompareValue_t = decltype(compare(*container.begin()));
  8. std::unordered_set<CompareValue_t> setUniqueValues;
  9. bool hasDuplicates = false;
  10. for (const auto & element : container)
  11. {
  12. CompareValue_t compareValue = compare(element);
  13. auto [_, successful] = setUniqueValues.insert(compareValue);
  14. if (!successful)
  15. {
  16. printf("Value '%s' is not unique.\n", std::to_string(compareValue).c_str());
  17. hasDuplicates = true;
  18. }
  19. }
  20. return hasDuplicates;
  21. }
  22. int main()
  23. {
  24. std::vector<int> a {1,2,2};
  25. HasDuplicates(a, [](auto x){ return x; });
  26. std::vector<S> b {{1, 0},{2, 1}, {2, 0}};
  27. HasDuplicates(b, [](auto x){ return x.idx; });
  28. return 0;
  29. }

标签:https://onlinegdb.com/bvOzbptnR

展开查看全部

相关问题