これは大きな質問です。
バイナリ検索の課題は、バイナリ検索の利点は、O(1)の各ステップで要素の半分をスキップできることにあります。これにより、O(lg n)個のプローブしか実行しないため、ランタイムはO(lg n)であることが保証されます。これは、たとえば、リンクリストではなく、配列に対して高速バイナリ検索を実行できる理由です。リンクされたリストでは、要素の途中点が線形時間をとり、検索の時間を支配します。
ファイルに対してバイナリ検索を実行すると、同じ位置にあります。ファイル内のすべての行の長さが同じでない可能性があるため、ファイル内のn行目にジャンプすることはできません。その結果、ファイルに対して良い、高速のバイナリ検索を実装するのはちょっと難しいでしょう。どういうわけか、効率的にファイル内をジャンプできるように、各行の開始と終了を知る必要があります。
これを行う方法はたくさんあります。まず、提案したように、ファイルから配列にすべての文字列をロードできます。これは線形時間を要しますが、メモリ内に文字列が配列されると、それ以降のバイナリ検索は非常に高速になります。あなたが非常に大きなファイルを持っているならば、これは大量のメモリを消費する可能性があり、非常に広大である可能性があるということです。その結果、配列に実際の刺し傷を格納するのではなく、各文字列が出現するファイルにオフセットを格納することもできます。これにより、バイナリ検索を素早く行うことができます。ファイルを比較するときに適切なオフセットを求めることができます。また、大きなスティングは、上記よりもはるかにスペース効率が良いことがあります。また、すべての文字列がほぼ同じ長さである場合は、各行の開始位置を直接計算できるように、すべての行を一定のサイズにパディングすることができます。
さらに複雑なソリューションを実装するのに少し時間を費やしたい場合は、ファイルの前処理を検討して、1行に1つの文字列を使用する代わりに、ファイルの先頭に固定長文字列ファイル内の各文字列のオフセットを含む幅の整数。これは本質的に上記の作業を行いますが、その後の結果をファイルに保存して、将来のバイナリ検索を高速化します。私はこの種のファイル構造についていくつかの経験があり、それはかなり速くなる可能性があります。
本当に挑戦している場合は、Bツリーを使用してファイルに文字列を格納することもできます。これにより、必要なディスク読み取り回数を最小限に抑えて各文字列を非常に高速に検索できますする。
希望すると便利です。
Cool。ありがとう男 – meburbo
正しい。メモリに読み込み、 'bsearch()'を使います。 – chrisaycock
ラインのオフセットを格納する必要はありません。 'O '(m log n)'の時刻に '' \ n ''に同期するバイナリ検索を単純に行うことができます。ここで' n'は行数、 'm'は任意の行の最大長です。これはメモリにファイルをロードできず、 'fseek' /' fseeko'を使用しなければならない場合でも動作します。 –