2016-07-12 6 views
0

次の検索を高速に行う方法はありますか? A配列の項目は、DESCの順序でソートされます。この検索のパフォーマンスを改善しますか?

+2

'std :: lower_bound'アルゴリズムです。 – ilotXXI

+1

検索の背後にあるロジックを簡単に説明できますか? 1つの動作は正確な一致を検索することですが、他の動作は私にはあまりあいまいです。 –

+0

@Tim Biegeleisenもう1つの動作は、完全に一致するものが見つからない場合に、最も近い項目を値未満の値に戻すことです。 – MATH000

答えて

1

あなたはあなたのケースでstd::lower_boundアルゴリズムを使用することができます

int left = 0; 
int right = items_no; // Exclusive 
while (left < right) { 
    int mid = (left + right)/2; 

    if (value == A[mid]) 
     return mid; 
    if (value < A[mid]) { 
     left = mid + 1; 
    } else { 
     right = mid; 
    } 
} 
return only_exact_match ? -1 : right - 1; // The greater 
+0

@Joop Eggen期待通りの結果を返しません... – MATH000

+0

@Holtループ内で完全一致が見つかった場合、私は半分返します。 –

+0

@JoopEggen申し訳ありませんが、それを逃した。 – Holt

1

あなたの配列はソートされているので、二等分に類似したステップで検索することができます。まず、あなたの価値に対して中点をチェックしてください。それが等しいなら、あなたはあなたの答えを持っています。値が大きければ、値は配列の下半分になります。そうでない場合、あなたの価値は上半分にあります。値を見つけるまで、または要素がなくなるまで、配列の残りの要素を二等分することによって、このプロセスを繰り返します。 2番目のif節について、一致する値が見つからない場合、要素i + 1が存在する場合(すなわち、配列の最後にない場合)、最も近い小さい要素が要素i + 1になります。

5

バイナリ検索。他の人が書いたように、O(log N)でバイナリ検索を実行します。これは次のようなものになります。

int find_pos(int A[], int value, int items_no, bool only_exact_match) 
{ 
    const int *pos_ptr = std::lower_bound(A, A + items_no, value, std::greater<int>()); 
    const ptrdiff_t pos = pos_ptr - A; 

    if (pos >= items_no) 
     return -1; 
    if (*pos_ptr != value && only_exact_match) 
     return -1; 
    return pos; 
} 
+2

小さなコメント: 'std :: greater()'は無効です。 std :: greater <>() '(C++ 14以上)または' std :: greater () '(C++ 11以降)が必要です。 – Holt

+0

はい、テンプレート引数が必要です。正直なところ私はこのコードをコンパイルしませんでした。それはほぼ必要なものです。 – ilotXXI

関連する問題