2009-07-15 14 views
6

Bir dosyadan dizelerin bir listesini okumak, bunları bir veri yapısına kaydetmek ve sonra da bu dizeleri öneklere göre arayın. Dizelerin listesi, yalnızca belirli bir dilde yazılmış sözcüklerin listesidir. Örneğin, arama fonksiyonu bir parametre olarak "stup" alırsa, ["stupid", "aptallık", "stupor" ...] döndürmelidir. O (log (n) * m) zamanında bunu yapmalıdır, burada n veri yapısının büyüklüğüdür ve m, sonuçların sayısıdır ve olabildiğince hızlı olmalıdır. Bellek tüketimi şu anda büyük bir sorun değil. Bunu pythonda yazıyorum, python sarmalayıcıları ile c içinde uygulanan uygun bir veri yapısına (tercihen) işaret ederseniz, bu harika olurdu.Hızlı ön ek arama ile dizelerin (yaklaşık 100.000) salt okunur bir listesi için en verimli veri yapısı

cevap

15

Bir parça istiyorsanız.

http://en.wikipedia.org/wiki/Trie

Ben Scrabble ve Boggle programlarında bunları kullandım. Tanımladığınız kullanım durumu için mükemmeller (hızlı önek araması).

Python'da bir tray oluşturmak için bazı örnek kodlar. Bu birkaç ay önce birlikte çektiğim bir Boggle programından. Kalan okuyucuya bir egzersiz olarak bırakılmıştır. Ancak, önek denetimi için temel olarak kök düğümde (words değişkeni) başlayan bir yönteme gereksinim duyarsınız, ardışık alt düğümler için önekin harflerini izler ve böyle bir yol bulunursa ve aksi halde yanlışsa True değerini döndürür.

class Node(object): 
    def __init__(self, letter='', final=False): 
     self.letter = letter 
     self.final = final 
     self.children = {} 
    def __contains__(self, letter): 
     return letter in self.children 
    def get(self, letter): 
     return self.children[letter] 
    def add(self, letters, n=-1, index=0): 
     if n < 0: n = len(letters) 
     if index >= n: return 
     letter = letters[index] 
     if letter in self.children: 
      child = self.children[letter] 
     else: 
      child = Node(letter, index==n-1) 
      self.children[letter] = child 
     child.add(letters, n, index+1) 

def load_dictionary(path): 
    result = Node() 
    for line in open(path, 'r'): 
     word = line.strip().lower() 
     result.add(word) 
    return result 

words = load_dictionary('dictionary.txt') 
+0

Ben iteratif yöntem olarak Node.add() yazmak için cazip olacaktır: def eklemek (öz, harf): sonraki = öz n = len (Harfler için (sayı) Harf, (Harf): ( next.children [mektup] = Düğüm (mektup, dizin == n-1) next = next.children [ mektup] – hughdbrown

+0

Ama doğru girinti ve çizgi ile hayal etmeye çalışın sonları. – hughdbrown

+0

Ayrıca, daha az bellek kullanan bir kaset olan "DAWG" konusuna da bakın. Fakat inşa etmek karmaşıktır (en azından bir trie'ye kıyasla). – Fantius

-1

dize dizisi. içinden

sonra ikili arama ilk maçı sonra burada da sonraki tüm maçları için içinden birer

(i başlangıçta bağladı listesini birinci adıma aramak ... ama tabii bu rastgele yok erişim nedenle bu (ı downvoted neden muhtemelen açıklar) 'bs' oldu Benim ikili arama algoritması hala gitmek için en hızlı yoldur olsa tries ait

+0

Tanrım, adama bir mola ver. – moo

+0

Birçok downvot ve neden kimse açıklamayı umursamıyor? İnsanların yığılması gibi hissettiriyor. Bu yanıt, orijinal kullanıcının talep ettiği tüm kısıtlamaları karşılar ve anlaşılması ve bakımı daha kolaydır. –

+0

@reinier - Bağlantılı listeler rastgele erişim için iyi olmadığından düştüğünüze inanıyorum, bu nedenle arama süreniz, öğe sayısında doğrusaldır. Bir dizi zaten sıralanırsa hızlıdır (ish), ancak O (log n) olur, oysa bir tray o (m) dir, burada m önekin uzunluğudur. –

İlgili konular