[英]C++/STL which algorithm should I use to check if a container has duplicates?
是否有任何STL算法可以判斷容器是否有重復的元素(使用operator==
或給定的謂詞)?
讓我們考慮這兩個向量:
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 1, 2, 1 };
我希望有這樣的功能:
std::is_exclusive( v1.begin(), v1.end() ); // returning true
std::is_exclusive( v2.begin(), v2.end() ); // returning false
有這么簡單的功能嗎? 我找不到任何(找到std::unique
,但這會修改向量...)
注意:我不是問如何“檢查一個容器是否有重復”,我知道我怎么做(基本上,我可以做( std::set<int>( v1.begin(), v1.end() ).size() == v1.size() )
並且可能存在許多其他選項。我在問是否有一個STL算法函數可以更聰明地完成它因為我很驚訝我找不到任何...
實現類似STL的is_exclusive
模板函數的一種方法是使用std::unordered_map
來保持范圍內元素的計數。 一旦任何元素的計數超過一個,函數模板就會返回false
:
#include <unordered_map>
template<typename ForwardIt>
bool is_exclusive(ForwardIt first, ForwardIt last) {
std::unordered_map<typename ForwardIt::value_type, unsigned> count;
for (auto it = first; it != last; ++it)
if (++count[*it] > 1)
return false;
return true;
}
對於你的例子:
int main() {
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 1, 2, 1 };
assert(is_exclusive(v1.begin(), v1.end()));
assert(!is_exclusive(v2.begin(), v2.end()));
}
我能做的唯一事情是https://en.cppreference.com/w/cpp/algorithm/adjacent_find ,但它要求對元素進行排序,因為它將檢查相鄰元素。
編輯:
沒有stl算法可以像你要求那樣做,另一種選擇是使用std :: any_of。
STL是關於效率和普遍性的。 似乎沒有通用且有效的方法來檢查容器是否有重復而不修改它。 因此,難怪STL中不存在這樣的算法。
一種方法是使用std :: set。
將矢量復制到集合中,並比較元素的數量是否相同。
如果是,則沒有重復,如果沒有,您可以猜出重復的數量。
#include <iostream>
#include <iterator>
#include <vector>
#include <set>
int has_duplicate(const std::vector<int> & v)
{
std::set<int> s(v.begin(), v.end());
return v.size() - s.size();
}
int
main()
{
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 1, 2, 1 };
std::cout << has_duplicate(v1) << std::endl;
std::cout << has_duplicate(v2) << std::endl;
}
對於v1,輸出為0 - >你沒有重復v2輸出是1 - >你有一個副本
算法成本為O(N * log(N))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.