比较binary_search

时间:2017-04-02 12:19:36

标签: c++ c++11 overloading binary-search

我正在尝试在自定义对象的矢量上运行binary_search。

struct T{
    string name;
    T(string n):name(n){};
    bool operator < (   T * n  ) const {
        return name < n ->  name;
    }
    bool operator == ( T * n ) const {
      return name == n -> name;
    }
};

    vector<T *> t;
    t.push_back(new T("one"));
    t.push_back(new T("two"));
    t.push_back(new T("three"));

bool has_3 = binary_search( t.begin(), t.end(), new T("two") ) ;
    if( has_3 ){
        cout <<"Its there" << endl;
    }

比较函数应该很好但是当我运行代码时has_3等于0 =元素不存在于向量中。这个问题是由我的超载引起的吗? ?我没有理由认为这不应该找到价值。考虑到插入到向量中的顺序,应该对其进行排序

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

有几个原因导致它找不到值:

  • 必须对范围进行排序;你的范围不按字母顺序排列
  • 您的比较功能是在TT*之间定义的,而您搜索T*的{​​{1}}向量。

您可以通过交换T*"two"来解决第一个问题,通过制作"three"的向量来解决第二个问题:

T

Demo 1.

如果你没有办法构建一个指针向量,你可以使用这个丑陋的解决方法(我强烈建议不要使用它):

struct T{
    string name;
    T(string n):name(n){};
    bool operator < (   const T &n  ) const {
        return name < n.name;
    }
    // operator == is not necessary for binary_search
};
int main() {
    vector<T> t;
    t.push_back(T("one"));
    t.push_back(T("three"));
    t.push_back(T("two"));
    bool has_3 = binary_search( t.begin(), t.end(), T("two") ) ;
    if( has_3 ){
        cout <<"Its there" << endl;
    }
    return 0;
}

现在您可以这样搜索:

struct T{
    string name;
    T(string n):name(n){};
};
bool operator < (const T& l, const T *r) {
    return l.name < r->name;
}
bool operator < (const T *l, const T &r) {
    return l->name < r.name;
}

Demo 2.

答案 1 :(得分:0)

使用指向动态分配对象的指针向量是一个非常愚蠢的要求。但这是一种可行的方法。

#include <iostream>
#include <string>
#include <algorithm>

struct T
{
    std::string name;
    T(std::string n):name(n){};
};

// this is the comparater needed to work with pointers, but it should
//    NOT be a member of T

bool pointer_comparer(const T *left, const T *right)
{
   // this assumes both left and right point to valid objects

    return left->name < right->name;
}

int main()
{
    std::vector<T *> t;
    t.push_back(new T("one"));
    t.push_back(new T("two"));
    t.push_back(new T("three"));

    //   t is unsorted.  We need to sort it since binary_search will
    //      ASSUME it is sorted

    std::sort(t.begin(), t.end(), pointer_comparer);

    T *value_needed = new T("two");    
    bool has_3 = std::binary_search( t.begin(), t.end(), value_needed, pointer_comparer);
    if(has_3)
    {
        std::cout <<"Its there" << std::endl;
    }

    //   since we've been stupidly allocating objects, we need to release them

    delete value_needed;
    for (std::vector<T *>::iterator i = t.begin(), end = t.end();
         i != end;  ++i)
    {
         delete (*i);
    }

    //   and since t now contains a set of dangling pointers, we need to discard them too

    t.resize(0);
    return 0;
}

为什么我要求使用指向动态分配对象的指针向量。将上述内容与使用vector<T>而不是vector<T *>的方法进行比较。

#include <iostream>
#include <string>
#include <algorithm>

struct T
{
    std::string name;
    T(std::string n):name(n){};
    bool operator < (const T &) const
    {
        return name < n.name;
    };
};

int main()
{
    std::vector<T> t;
    t.push_back(T("one"));
    t.push_back(T("two"));
    t.push_back(T("three"));

    //   t is unsorted.  We need to sort it since binary_search will
    //      ASSUME it is sorted

    std::sort(t.begin(), t.end());
    bool has_3 = std::binary_search(t.begin(), t.end(), T("two"));
    if(has_3)
    {
        std::cout <<"Its there" << std::endl;
    }

    //  we need do nothing here.  All objects use above will be properly released

    return 0;
}

注意:我已经编写了上述内容,因此它适用于所有C ++标准。假设C ++ 11及更高版本,在这两种情况下都可以进行简化。