bsearch包装器

时间:2012-06-05 23:44:15

标签: c++ templates lambda c++11

前一段时间我只是玩弄搜索算法,经过几个基准测试后,我看到老bsearch()与std :: binary_search()相比有多快,我印象深刻。我认为任何体面的编译器都可以在可能的情况下用bsearch()代替std :: binary_search(),但即使我使用的是GCC 4.7,bsearch似乎也比std :: binary_search快5倍。< / p>

所以我认为尝试使用与std :: binary_search相同的接口为bsearch创建某种包装器是一个很好的练习。但由于一个未知的原因,我没有设法做到这一点。这是我的代码:

template<typename InputIterator, class T>
bool binary_search(InputIterator first, InputIterator last, const T& value)
{
    auto cmp = [](const void* a, const void* b)
    {
        return (int) ((*(T*)a) == (*(T*)b));
    };

    std::cout << value << std::endl;
    T* res = (T*) bsearch(&value, first, last-first, sizeof(*first), cmp);
    return res != nullptr;
}

代码编译良好,并且在执行时不会崩溃。但是,似乎bsearch在一次内部迭代后立即停止(* res总是等于作为参数传递的选项卡中间的值)。我无法找到它为什么不起作用。所以,如果可能的话,一点帮助就没问题了。

感谢。


对于那些要求用于检查速度的代码的人:

const std::string keyword_str[] = {
    // Some strings
};

int cmp(const void* s1, const void* s2)
{
    return (int) ((*(std::string*)s1) == (*(std::string*)s2));
}

int main()
{
    time_t start, end;
    double dif;
    time (&start);

    // Code
    for (const string& str: keyword_str)
    {
        for (size_t i = 0 ; i < 1000000 ; ++i)
        {
            // std::binary_search (uncomment to check)
            //bool a = std::binary_search(keyword_str, keyword_str+28, str);

            // bsearch
            char** st = (char**) bsearch(&str, keyword_str, 28, sizeof(keyword_str[0]), cmp);
        }
    }

    time (&end);
    dif = difftime (end, start);
    printf("Time spent: %fs.\n", dif);

    return 0;
}

2 个答案:

答案 0 :(得分:3)

bsearch接受一个函数指针,cmp不是函数指针。 (编辑:我错了。由于cmp没有捕获任何变量 - 它的括号是空的 - 它可以作为函数指针传递。这种行为在§5.1.2/ 6的C ++ 11标准。)

bsearch也不会返回比较函数预期返回的正确值。如果键小于数组元素,则应返回-1;如果键相等则返回0;如果键大于数组元素,则返回1。如果cmp函数不相等则返回0,如果它们相等则返回1。因此,如果您要比较的第一个元素与键不相等,那么cmp会使bsearch认为它们相等且bsearch停止,因为它认为它找到了正确的元素立即。

答案 1 :(得分:2)

一般情况下,无法使用bsearch来实现std::binary_search,因为bsearch只能搜索连续的元素数组,而std::binary_search可以在一系列元素上搜索迭代器,适用于任何迭代器类型。它可以是链表迭代器,deque迭代器或用户创建的一些自定义异域迭代器。显然没有办法用bsearch

搜索这些迭代器