наиболее эффективная структура данных для списка строк только для чтения (около 100 000) с быстрым поиском по префиксу - PullRequest
6 голосов
/ 15 июля 2009

Я пишу приложение, которое должно прочитать список строк из файла, сохранить их в структуре данных, а затем искать эти строки по префиксам. Список строк - это просто список слов на данном языке. Например, если функция поиска получает «stup» в качестве параметра, она должна вернуть [«stupid», «stupidity», «stupor» ...]. Это следует делать за время O (log (n) * m), где n - размер структуры данных, а m - количество результатов и должно быть максимально быстрым. Потребление памяти не является большой проблемой прямо сейчас. Я пишу это на python, поэтому было бы здорово, если бы вы указали мне подходящую структуру данных (предпочтительно), реализованную в c с помощью оболочек python.

Ответы [ 4 ]

15 голосов
/ 15 июля 2009

Вы хотите три.

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

Я использовал их в программах Scrabble и Boggle. Они идеально подходят для описанного вами варианта использования (быстрый поиск префиксов).

Вот пример кода для построения дерева в Python. Это из программы Boggle, которую я взбил несколько месяцев назад. Остальное оставлено в качестве упражнения для читателя. Но для проверки префикса вам в основном нужен метод, который начинается с корневого узла (переменная words), следует буквам префикса последующим дочерним узлам и возвращает True, если такой путь найден, и False в противном случае.

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')
4 голосов
2 голосов
/ 15 июля 2009

A три (или дерево префиксов) звучит прямо в вашем переулке. Я думаю, он может выполнять поиск по строке префикса длины m в O (m).

0 голосов
/ 15 июля 2009

строковый массив.

затем бинарный поиск по нему для поиска первого соответствия затем шаг за шагом пройдитесь по нему для всех последующих совпадений

(у меня изначально тоже был здесь связанный список ... но, конечно, у него нет произвольного доступа, поэтому это был "bs" (что, вероятно, объясняет, почему меня опровергли). Мой алгоритм двоичного поиска все еще является самым быстрым иди хотя бы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...