我想检查一个整数向量是否有任何重复,如果有,就必须返回true。所以我试着这样做:
vector<int> uGuess = {1,2,3,3,4,5}vector<int> a = uGuess;sort(a.begin(), a.end());bool d = unique(a.begin(), a.end());
vector<int> uGuess = {1,2,3,3,4,5}
vector<int> a = uGuess;
sort(a.begin(), a.end());
bool d = unique(a.begin(), a.end());
这将不起作用,因为unqiue不能被分配为bool值。我该如何着手呢?如果我写一个for循环来执行相同的操作,我应该怎么做?
e5nszbig1#
你要找的算法是std::adjacent_find。
std::adjacent_find
// The container must be sorted!const std::vector<int> sortedVector = {1,2,3,3,4,5};const bool hasDuplicates = std::adjacent_find(sortedVector.begin(), sortedVector.end()) != sortedVector.end();
// The container must be sorted!
const std::vector<int> sortedVector = {1,2,3,3,4,5};
const bool hasDuplicates = std::adjacent_find(sortedVector.begin(), sortedVector.end()) != sortedVector.end();
与std::unique不同,std::adjacent_find不会修改容器。作为奖励,std::adjacent_find返回重复“对”中第一个元素的迭代器:
std::unique
const auto duplicate = std::adjacent_find(sortedVector.begin(), sortedVector.end());if (duplicate != sortedVector.end()) std::cout << "Duplicate element = " << *duplicate << "\n";
const auto duplicate = std::adjacent_find(sortedVector.begin(), sortedVector.end());
if (duplicate != sortedVector.end())
std::cout << "Duplicate element = " << *duplicate << "\n";
gopyfrb32#
你应该使用set
set<int> s(a.begin(), a.end());return s.size() != a.size();
set<int> s(a.begin(), a.end());
return s.size() != a.size();
ergxz8rk3#
在google搜索std::unique时,我找到了这个页面std::unique。我看了看它做了什么:从[first,last]范围内的每个连续等效元素组中删除除第一个元素之外的所有元素所以它看起来像你想要的-删除重复。然后我看了看它返回的内容.....所以std::unique的结果是一个序列,它不一定与整个vector相同。如果没有删除任何内容,则返回值将是vector的结尾。因此,您需要:
vector
vector<int>::iterator it = std::unique(a.begin(), a.end());bool wasUnique = (it == a.end());
vector<int>::iterator it = std::unique(a.begin(), a.end());
bool wasUnique = (it == a.end());
对于C++11:
auto it = std::unique(a.begin(), a.end());bool wasUnique = (it == a.end());
auto it = std::unique(a.begin(), a.end());
最后,为了使唯一函数正常工作,需要对vector进行排序,因此完整的代码如下:
sort(a.begin(), a.end());auto it = std::unique(a.begin(), a.end());bool wasUnique = (it == a.end());
lymgl2op4#
如果有人被迫写自己的算法:
bool hasDuplicates(const std::vector<int>& arr) { for (std::size_t i = 0; i < arr.size(); ++i) { for (std::size_t j = i + 1; j < arr.size(); ++j) { if (arr[i] == arr[j]) return true; } } return false;}
bool hasDuplicates(const std::vector<int>& arr) {
for (std::size_t i = 0; i < arr.size(); ++i) {
for (std::size_t j = i + 1; j < arr.size(); ++j) {
if (arr[i] == arr[j])
return true;
}
return false;
但是在真实的代码中,你应该使用已经存在的东西,在标准库中。
pw9qyyiw5#
如果向量还没有排序,则对它进行排序,然后使用std::unique(),如下所示:
std::unique()
#include <iostream>#include <vector>#include <algorithm>int main() { std::vector<int> v = {3, 1, 3, 4, 5}; sort(v.begin(), v.end()); auto it = std::unique(v.begin(), v.end()); std::cout << ((it == v.end()) ? "Unique\n" : "Duplicate(s)\n"); return 0;}
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {3, 1, 3, 4, 5};
sort(v.begin(), v.end());
auto it = std::unique(v.begin(), v.end());
std::cout << ((it == v.end()) ? "Unique\n" : "Duplicate(s)\n");
return 0;
输出量:重复
nnt7mjpx6#
到目前为止,所有这些解决方案要么修改容器,要么具有O(n²)的复杂度。你可以把std::map放到更好的用途:
#include <algorithm>#include <iterator>#include <map>template <typename Iterator>bool has_duplicates( Iterator first, Iterator last ){ std::map <typename std::iterator_traits <Iterator> ::value_type, std::size_t> histogram; while (first != last) if (++histogram[ *first++ ] > 1) return true; return false;}#include <iostream>#include <vector>int main(){ using std::begin; using std::end; int a[] = { 2, 3, 5, 7, 11 }; int b[] = { 2, 3, 5, 5, 7 }; std::vector <int> c( begin(a), end(a) ); std::vector <int> d( begin(b), end(b) ); std::cout << std::boolalpha; std::cout << "a has duplicates false : " << has_duplicates( begin(a), end(a) ) << "\n"; std::cout << "b has duplicates true : " << has_duplicates( begin(b), end(b) ) << "\n"; std::cout << "c has duplicates false : " << has_duplicates( begin(c), end(c) ) << "\n"; std::cout << "d has duplicates true : " << has_duplicates( begin(d), end(d) ) << "\n";}
#include <iterator>
#include <map>
template <typename Iterator>
bool has_duplicates( Iterator first, Iterator last )
{
std::map <typename std::iterator_traits <Iterator> ::value_type, std::size_t> histogram;
while (first != last)
if (++histogram[ *first++ ] > 1)
int main()
using std::begin;
using std::end;
int a[] = { 2, 3, 5, 7, 11 };
int b[] = { 2, 3, 5, 5, 7 };
std::vector <int> c( begin(a), end(a) );
std::vector <int> d( begin(b), end(b) );
std::cout << std::boolalpha;
std::cout << "a has duplicates false : " << has_duplicates( begin(a), end(a) ) << "\n";
std::cout << "b has duplicates true : " << has_duplicates( begin(b), end(b) ) << "\n";
std::cout << "c has duplicates false : " << has_duplicates( begin(c), end(c) ) << "\n";
std::cout << "d has duplicates true : " << has_duplicates( begin(d), end(d) ) << "\n";
8ulbf1ek7#
如果你的vector很小,比如< 32个对象,或者如果由于缺少移动或复制构造函数/赋值而复制和排序对象是昂贵的或不可能的,那么直接的O(n^2)比较所有的东西都是其他的算法。以下是我的解决方案:
O(n^2)
template <typename Iterator>bool has_duplicates( Iterator first, Iterator end ) { for (auto i = first; i != end; ++i) { for (auto j = first; i != j; ++j) { if (*i == *j) return true; } } return false;}template <typename Container>bool has_duplicates(const Container &v) { for (const auto & i : v) { for (const auto & j : v) { if (&i == &j) break; if (i == j) return true; } } return false;}
bool has_duplicates( Iterator first, Iterator end ) {
for (auto i = first; i != end; ++i) {
for (auto j = first; i != j; ++j) {
if (*i == *j) return true;
template <typename Container>
bool has_duplicates(const Container &v) {
for (const auto & i : v) {
for (const auto & j : v) {
if (&i == &j) break;
if (i == j) return true;
iyfamqjs8#
如果你有一个更复杂的向量,想知道哪个值是重复的,你可以这样做:
#include <vector>#include <unordered_set>#include <string>template <typename InputContainer_t, typename GetCompareValueLambda_t>bool HasDuplicates(const InputContainer_t& container, GetCompareValueLambda_t compare){ using CompareValue_t = decltype(compare(*container.begin())); std::unordered_set<CompareValue_t> setUniqueValues; bool hasDuplicates = false; for (const auto & element : container) { CompareValue_t compareValue = compare(element); auto [_, successful] = setUniqueValues.insert(compareValue); if (!successful) { printf("Value '%s' is not unique.\n", std::to_string(compareValue).c_str()); hasDuplicates = true; } } return hasDuplicates;}int main(){ std::vector<int> a {1,2,2}; HasDuplicates(a, [](auto x){ return x; }); std::vector<S> b {{1, 0},{2, 1}, {2, 0}}; HasDuplicates(b, [](auto x){ return x.idx; }); return 0;}
#include <unordered_set>
#include <string>
template <typename InputContainer_t, typename GetCompareValueLambda_t>
bool HasDuplicates(const InputContainer_t& container, GetCompareValueLambda_t compare)
using CompareValue_t = decltype(compare(*container.begin()));
std::unordered_set<CompareValue_t> setUniqueValues;
bool hasDuplicates = false;
for (const auto & element : container)
CompareValue_t compareValue = compare(element);
auto [_, successful] = setUniqueValues.insert(compareValue);
if (!successful)
printf("Value '%s' is not unique.\n", std::to_string(compareValue).c_str());
hasDuplicates = true;
return hasDuplicates;
std::vector<int> a {1,2,2};
HasDuplicates(a, [](auto x){ return x; });
std::vector<S> b {{1, 0},{2, 1}, {2, 0}};
HasDuplicates(b, [](auto x){ return x.idx; });
标签:https://onlinegdb.com/bvOzbptnR
8条答案
按热度按时间e5nszbig1#
你要找的算法是
std::adjacent_find
。与
std::unique
不同,std::adjacent_find
不会修改容器。作为奖励,
std::adjacent_find
返回重复“对”中第一个元素的迭代器:gopyfrb32#
你应该使用set
ergxz8rk3#
在google搜索
std::unique
时,我找到了这个页面std::unique。我看了看它做了什么:从[first,last]范围内的每个连续等效元素组中删除除第一个元素之外的所有元素
所以它看起来像你想要的-删除重复。
然后我看了看它返回的内容...
..
所以
std::unique
的结果是一个序列,它不一定与整个vector
相同。如果没有删除任何内容,则返回值将是
vector
的结尾。因此,您需要:
对于C++11:
最后,为了使唯一函数正常工作,需要对
vector
进行排序,因此完整的代码如下:lymgl2op4#
如果有人被迫写自己的算法:
但是在真实的代码中,你应该使用已经存在的东西,在标准库中。
pw9qyyiw5#
如果向量还没有排序,则对它进行排序,然后使用
std::unique()
,如下所示:输出量:
重复
nnt7mjpx6#
到目前为止,所有这些解决方案要么修改容器,要么具有O(n²)的复杂度。你可以把std::map放到更好的用途:
8ulbf1ek7#
如果你的vector很小,比如< 32个对象,或者如果由于缺少移动或复制构造函数/赋值而复制和排序对象是昂贵的或不可能的,那么直接的
O(n^2)
比较所有的东西都是其他的算法。以下是我的解决方案:
iyfamqjs8#
如果你有一个更复杂的向量,想知道哪个值是重复的,你可以这样做:
标签:https://onlinegdb.com/bvOzbptnR