Sıralanmış bir metin dosyasında ikili arama


13

Değişken uzunlukta milyarlarca satır içeren büyük bir sıralanmış dosyam var. Yeni bir satır verilen sıralı dosyaya dahil olsaydı hangi bayt numarasını alacağını bilmek istiyorum.

Misal

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

'Foo' girdisi göz önüne alındığında, çıktıyı 9 alırdım.

Bu, tüm dosyayı inceleyerek yapmak kolaydır, ancak milyarlarca değişken uzunlukta satır olarak, ikili bir arama yapmak daha hızlı olacaktır.

Böyle bir metin işleme aracı zaten var mı?

Düzenle:

Şimdi çalışıyor: https://gitlab.com/ole.tange/tangetools/blob/master/bsearch/bsearch


Aradığınız satır ne kadar (karakter cinsinden)? ve kaç tane satır aramanız gerekiyor?
gogoud

@gogoud Sınırlı bir araç arıyorum, ancak herhangi bir metin dosyası üzerinde çalışan bir satır arıyorum (satır uzunluğu veya satır sayısı ne olursa olsun).
Ole Tange

böyle devasa girdiler üretmek isteyenler için: unix.stackexchange.com/a/279098/9689
Grzegorz Wierzowiecki

Yanıtlar:


4

Bunu yapan bazı standart araçların farkında değilim. Ancak kendi yazabilirsiniz. Örneğin, aşağıdaki yakut komut dosyası işi yapmalıdır.

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

Biraz zor çünkü aramadan sonra genellikle bir satırın ortasındasınız ve bu nedenle aşağıdaki satırın başlangıcına ulaşmak için bir okuma satırı yapmanız gerekir, bu anahtarınızı okuyabilir ve karşılaştırabilirsiniz.


O / -r süreç dosyalarına göre sınıflandırılmaktadır -n kabul etmek değiştirilebilir sort -rve sort -n?
Ole Tange

Yukarıdaki kod esas olarak fikri göstermek içindir. Mükemmel olmaktan uzak. (Örneğin, anahtar ilk sırada olursa başarısız olur.) Gereksinimlerinize uyum sağlamaktan çekinmeyin.
michas

5

(Bu sorunuza doğru bir cevap değil, sadece bir başlangıç ​​noktasıdır.)

Benzer bir durumda sgrep (sıralanmış grep) kullandım .

Ne yazık ki (şu anki duruma ihtiyacımız var) bayt-offset çıktısı yok; ama bence kolayca eklenebilir.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.