C ++ / STL应该使用哪种算法检查容器是否重复?

时间:2018-08-22 09:55:06

标签: c++ stl

是否有任何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算法功能可以用一种更智能的方式来实现它,因为我很惊讶我找不到任何...

4 个答案:

答案 0 :(得分:3)

实现类似STL的void main() => runApp(MaterialApp(home: Home())); class Home extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: RaisedButton( child: Text('Open Dialog'), onPressed: () { showDialog( context: context, builder: (_) { return MyDialog(); }); }, ))); } } class MyDialog extends StatefulWidget { @override _MyDialogState createState() => new _MyDialogState(); } class _MyDialogState extends State<MyDialog> { Color _c = Colors.redAccent; @override Widget build(BuildContext context) { return AlertDialog( content: Container( color: _c, height: 20.0, width: 20.0, ), actions: <Widget>[ FlatButton( child: Text('Switch'), onPressed: () => setState(() { _c == Colors.redAccent ? _c = Colors.blueAccent : _c = Colors.redAccent; })) ], ); } } 模板函数的一种方法是使用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;
}

答案 1 :(得分:2)

我唯一能做的就是https://en.cppreference.com/w/cpp/algorithm/adjacent_find,但是它要求对元素进行排序,因为它将检查相邻的元素。

编辑:

没有stl算法可以满足您的要求,另一种选择是使用std :: any_of。

答案 2 :(得分:2)

STL与效率和普遍性有关。似乎没有通用且有效的方法来检查容器是否有重复项而不进行修改。因此,难怪STL中没有这样的算法。

答案 3 :(得分:0)

一种方法是使用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))