簡體   English   中英

C ++ / STL我應該使用哪種算法來檢查容器是否有重復?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM