在集合中查找结构的向量

时间:2015-02-10 09:51:12

标签: c++

我正在尝试在集合中找到结构的向量。为此,我编写了以下代码:

#include <cstdlib>
#include <iostream>
#include <set>
#include <vector>

using namespace std;

struct A{
    int a;
};

int main(int argc, char** argv) {

    std::set< std::vector<A> > aObj;
    A a1,a2,a3,a4,a5,a6;
    a1.a=5; a2.a=8; a3.a=10;
    a4.a=5; a5.a=8; a6.a=10;
    vector<A> vecA,vecB;
    vecA.push_back(a1); vecA.push_back(a2); vecA.push_back(a3);
    aObj.insert(vecA);
    set< vector<A> >::iterator it = aObj.find(vecB);
    if (it != myset.end()) {
        cout<<"\n Found vector B. \n";
    }    
    return 0;
}

但是,上面的代码给出了以下错误:

/usr/include/c++/4.6/bits/stl_algobase.h:881:6: error: no match for ‘operator<’ in ‘* __first1 < * __first2’
/usr/include/c++/4.6/bits/stl_algobase.h:881:6: note: candidates are:
/usr/include/c++/4.6/bits/stl_pair.h:207:5: note: template<class _T1, class _T2> bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
/usr/include/c++/4.6/bits/stl_iterator.h:291:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/stl_iterator.h:341:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/basic_string.h:2510:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2522:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/basic_string.h:2534:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)

2 个答案:

答案 0 :(得分:4)

另一个答案很好地解释了。如果A defines a weak total ordering (e.g. by implementing operator<)您能够找到这些向量。

以下是如何使代码更简洁:

<强> Live On Coliru

#include <iostream>
#include <set>
#include <vector>

struct A {
    int a;
    bool operator<(A const &other) const { return a < other.a; }
};

int main() {
    std::set<std::vector<A> > myset{ 
        { { 4 }, { 7 }, { 9 } },
        { { 5 }, { 8 }, { 10 } },
        { { 6 }, { 9 }, { 11 } },
    };

    auto it = myset.find({ {1}, {2}, {3} });
    std::cout << "Found vector: " << std::boolalpha << (it != myset.end()) << "\n"; 

    it = myset.find({ {5}, {8}, {10} });
    std::cout << "Found vector: " << std::boolalpha << (it != myset.end()) << "\n"; 
}

打印

Found vector: false
Found vector: true

这为A使用聚合初始化vectorset容器的统一初始化({a,b,c}将使用std::initialializer_list<>构造函数重载)

答案 1 :(得分:3)

就像现在一样,std::set::find正试图使用​​std::less<std::vector<A>>将给定的向量与集合中的向量进行比较,std::set<std::vector<A>>bool operator<(const std::vector<A>& lhs, const std::vector<A>& rhs) const实例的默认比较器。 AFAIK,std :: less将调用std::less<A>来比较向量,这将依次使用std::less<A>对向量进行字典比较。然后,bool A::operator<(const A& rhs) const会尝试调用bool operator<(const A& lhs, const A& rhs) const(成员函数版本)或A(自由函数版本)来比较struct A的实例。这是失败的,因为这些功能都不存在。

您有两种选择:

1)您为bool operator<(const A& rhs) const { return a < rhs.a; } 配备了一个比较运算符(在本例中,我们将其作为成员函数),如下所示:

std::vector

并依赖于operator<执行std::set,执行词典比较。字典比较意味着成对地比较矢量元素,直到找到被比较的两个矢量的元素对(x,y),其中x <1。 y或y&lt; X。如果不存在这样的对,则两个向量被认为是相等的,除非它们具有不同的长度,在这种情况下,较短的向量是较长的向量的前缀,并且考虑较少。

2)您为std::vector提供了一个可以比较矢量的比较器,具体来说,确定两个矢量中哪一个小于另一个。这仅在您不想使用struct VecCmp { bool operator<(const std::vector<A>& lhs, const std::vector<A>& rhs) const { // determine whether lhs is less than rhs and return true if so, false otherwise } }; 的词典编纂比较并且您可以在矢量上定义弱总排序时才有用。如果是这种情况,那么你可以像这样实现一个比较器:

std::set

然后将std::set<std::vector<A>, VecCmp> myset(VecCmp()); 配置为使用此比较器,如下所示:

{{1}}
相关问题