1

しばらく前に検索アルゴリズムをいじっていたところ、いくつかのベンチマークを行った後、古いbsearch()がstd :: binary_search()と比較してどれだけ高速であるかを確認したことに感銘を受けました。適切なコンパイラであれば、可能な場合はstd :: binary_search()をbsearch()に置き換えることができると思いましたが、GCC 4.7を使用していても、bsearchはstd::binary_searchの5倍の速度で実行されるようです。

そのため、同じインターフェイスを使用してbsearchのラッパーを作成し、std::binary_searchを作成するのは素晴らしい演習になると思いました。しかし、理由は不明ですが、なんとかできませんでした。これが私のコードです:

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は1回の内部反復の直後に停止するようです(* 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;
}
4

2 に答える 2

3

bsearchは関数ポインタを取り、関数ポインタでcmpはありません。(編集:これについては間違っていました。cmp変数をキャプチャしないため-括弧は空です-関数ポインターとして渡すことができます。この動作は、C ++ 11の§5.1.2 / 6で指定されています標準。)

bsearchまた、比較関数が返すと予想される正しい値を返しません。キーが配列要素より小さい場合は -1、等しい場合は 0、キーが配列要素より大きい場合は 1 を返します。関数cmpは、等しくない場合は 0 を返し、等しい場合は 1 を返します。その結果、比較している最初の要素がキーとcmp等しくない場合、makebsearchはそれらが等しいとbsearch判断し、正しい要素がすぐに見つかったと判断して停止します。

于 2012-06-05T23:59:51.700 に答える
2

一般に、要素の連続した配列のみを検索できるためbsearch、実装に使用することはできませんが、任意のイテレーター型について、イテレーターの範囲で機能します。これは、リンクされたリスト反復子、deque 反復子、またはユーザーが作成したカスタムのエキゾチックな反復子である可能性があります。これらのイテレータを検索する方法は明らかにありませんstd::binary_searchbsearchstd::binary_searchbsearch

于 2012-06-06T03:53:19.340 に答える