web-dev-qa-db-ja.com

ソートされたテキストファイルでのバイナリ検索

可変長の数十億行の大きなソート済みファイルがあります。新しい行が与えられたので、ソートされたファイルに含まれている場合、どのバイト番号が得られるかを知りたいと思います。

a\n
c\n
d\n
f\n
g\n

入力が 'foo'の場合、出力は9になります。

これはファイル全体を調べるだけで簡単ですが、可変長の数十億行であるため、バイナリ検索を実行する方が高速です。

そのようなテキスト処理ツールはすでに存在していますか?

編集:

現在は次のようになっています: https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch

13
Ole Tange

私はこれを行ういくつかの標準的なツールを知りません。しかし、あなたはあなた自身のものを書くことができます。たとえば、次のRubyスクリプトがその仕事をするはずです。

file, key = ARGV.shift, ARGV.shift
min, max = 0, File.size(file)

File.open(file) do |f|
  while max-min>1 do
    middle = (max+min)/2
    f.seek middle
    f.readline
    if f.eof? or f.readline>=key
      max = middle
    else
      min = middle
    end
  end
  f.seek max
  f.readline
  p f.pos+1
end

シーク後は通常、ある行の真ん中にあり、次の行の先頭に到達するために1行のreadlineを実行する必要があるため、少し注意が必要です。この行を読み取って、キーと比較できます。

4
michas

(これはあなたの質問に対する正しい答えではなく、単なる出発点です。)

同様の状況で sgrep (ソートされたgrep)を使用しました。

残念ながら(現在の状態が必要です)、バイトオフセット出力がありません。簡単に追加できると思います。

5
JJoao

Michasソリューションに基づいた、ここに、より完全なプログラムがあります。

https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch

0
Ole Tange