0

ハッシュまたは PHP のような配列を実装したいと考えています。キーで要素を検索するには、オプション a) またはオプション b) のどちらが優れていますか?

(すべての変数が設定され、初期化されます!)

a)

for( i = 0; i < ary->element_cnt && found == NULL; i++ ) {
    current_element = &(ary->elements[i]);
    if( 0 == memcmp(current_element->key, search_key, keysize) ) {
        found = current_element;
    }
}

b)

for( i = 0, current_element = &(ary->elements[i]) ; 
        i < ary->element_cnt &&  
        0 != memcmp(current_element->key, searchkey, keysize); 
        i++, current_element = &(ary->elements[i]) );
/*found = current_element;*/

最初のほうが読みやすい/保守しやすいので、より良いですか? 2番目の方が速いでしょうか?

すべてを 1 つの大きなループで行うのは「悪いスタイル」ですか?

もっと良い検索アルゴリズムがあることは知っていますが、それは私の問題ではありません!

4

2 に答える 2

5

これらは両方ともO(N)アルゴリズムであり、どちらも配列をループしてmemcmp各要素を呼び出すだけなので、同様に実行する必要があります。主観的には、最初のものの方が読みやすいので良いと思います。

ただし、キーによるルックアップを実装する最良の方法は、このような線形検索ではなく、ハッシュテーブルや平衡二分木などの特殊なデータ構造を使用することです。PHPのようなスクリプト言語は、通常、ハッシュテーブルを使用してこのようなルックアップを実装します。

于 2012-12-11T16:15:34.437 に答える
3

もちろん、スタイルのすべての問題は非常に主観的です。これは、ローカルコードスタイルガイドによって「規制」されることがあるタイプのことです。

memcmp()個人的には、への呼び出しは少し「重すぎる」と思います。次のように記述します。

for( i = 0; i < ary->element_cnt; ++i ) {
    current_element = &ary->elements[i];
    if( memcmp(current_element->key, search_key, keysize) == 0 )
        break;
}

これはループヘッダーのチェックをカットしfoundます。これは、私が嫌いな同じことを2回効果的にチェックしているためです。

本当に使いたいのならfound、次のように書きます。

for( i = 0; i < ary->element_cnt && !found; ++i ) {
    current_element = &ary->elements[i];
    found = memcmp(current_element->key, search_key, keysize) == 0;
}

これは無意味なものを取り除き、ifブール値を直接割り当てるだけです。これは素晴らしいと思います。

于 2012-12-11T16:16:33.170 に答える