列出字典中以<user input =“”> </user>开头的所有单词

时间:2008-09-21 23:28:07

标签: python list dictionary

如何制作用户输入字符串的程序,程序会生成以该字符串开头的单词列表?

例如:
用户:“abd”
计划:退位,腹部,绑架......

谢谢!


编辑:我正在使用python,但我认为这是一个与语言无关的问题。

16 个答案:

答案 0 :(得分:10)

使用trie

将您的单词列表添加到trie中。从根到叶子的每条路径都是有效的单词。从根节点到中间节点的路径表示前缀,中间节点的子节点是前缀的有效完成。

答案 1 :(得分:8)

执行此操作的最佳方法之一是使用有向图来存储字典。它需要一些设置,但一旦完成,那么你很容易做你正在谈论的搜索类型。

图中的节点对应于单词中的字母,因此每个节点将有一个传入链接,最多26个(英文)传出链接。

您还可以使用混合方法,在该方法中维护包含字典的排序列表,并使用有向图作为字典的索引。然后,您只需在有向图中查找前缀,然后转到字典中的该点,并吐出符合搜索条件的所有字词。

答案 2 :(得分:6)

如果你在debian [-like]机器上,

#!/bin/bash
echo -n "Enter a word: "
read input
grep "^$input" /usr/share/dict/words

在我的P200上占用0.040全部。

答案 3 :(得分:4)

egrep `read input && echo ^$input` /usr/share/dict/words

哦,我没有看到Python编辑,这在python中是一回事

my_input = raw_input("Enter beginning of word: ")
my_words = open("/usr/share/dict/words").readlines()
my_found_words = [x for x in my_words if x[0:len(my_input)] == my_input]

答案 4 :(得分:4)

如果你真的想要速度,请使用trie / automaton。但是,考虑到单词列表的排序,这将比简单地扫描整个列表更快:

from itertools import takewhile, islice
import bisect

def prefixes(words, pfx):
    return list(
             takewhile(lambda x: x.startswith(pfx), 
                       islice(words, 
                              bisect.bisect_right(words, pfx), 
                              len(words)))

请注意,自动机的字典大小为O(1),而此算法为O(log(m)),然后是O(n)关于实际以字符串开头的字符串数量前缀,而全扫描是O(m),n <&lt;&lt;米。

答案 5 :(得分:2)

def main(script, name):
    for word in open("/usr/share/dict/words"):
        if word.startswith(name):
            print word,

if __name__ == "__main__":
    import sys
    main(*sys.argv)

答案 6 :(得分:2)

如果你真的想要高效 - 使用后缀树或后缀数组 - wikipedia article

您的问题是后缀树的设计目的。 甚至还有Python的实现 - here

答案 7 :(得分:1)

var words = from word in dictionary
            where word.key.StartsWith("bla-bla-bla");
            select word;

答案 8 :(得分:1)

尝试使用正则表达式搜索您的单词列表,例如/ ^ word /并报告所有匹配。

答案 9 :(得分:1)

如果你需要快速 ,请使用树:

构建一个数组并根据第一个字母拆分26组中的单词,然后根据第二个字母拆分26中的每个项目,然后再次。

因此,如果您的用户键入“abd”,您将查找Array [0] [1] [3]并获取所有单词的列表。此时,您的列表应该足够小,可以传递给客户端并使用javascript进行过滤。

答案 10 :(得分:1)

大多数Pythonic解决方案

# set your list of words, whatever the source
words_list = ('cat', 'dog', 'banana')
# get the word from the user inpuit
user_word = raw_input("Enter a word:\n")
# create an generator, so your output is flexible and store almost nothing in memory
word_generator = (word for word in words_list if word.startswith(user_word))

# now you in, you can make anything you want with it 
# here we just list it :

for word in word_generator :
    print word

记住生成器只能使用一次,因此将其转换为列表(使用list(word_generator))或使用itertools.tee函数(如果您希望多次使用它)。

最佳方式:

将其存储到数据库中并使用SQL查找所需的单词。如果你的词典里有很多单词,它会更加快速有效。

Python有数以千计的DB API来帮助你完成工作; - )

答案 11 :(得分:1)

您可以使用str.startswith()。记录到官方文档:

str.startswith(前缀[,开始[,结束]])

如果字符串以前缀开头,则返回True,否则返回False。 prefix也可以是要查找的前缀的元组。使用可选的开始,测试字符串从该位置开始。在可选端,停止在该位置比较字符串。

如下所示:

user_input = input('Enter something: ')
for word in dictionary:
    if str.startswith(user_input):
        return word

答案 12 :(得分:0)

如果您的字典非常大,我建议使用python文本索引进行索引(PyLucene - 请注意,我从未使用过lucene的python扩展名)搜索效率很高,您甚至可以返回搜索结果”。

另外,如果你的字典是相对静态的,你甚至不会经常重新编制索引。

答案 13 :(得分:0)

不要用火箭筒杀死苍蝇。使用像SQLite一样简单的东西。每种现代语言都有您需要的所有工具,您可以这样做:

"SELECT word FROM dict WHERE word LIKE "user_entry%"

快闪电,宝宝可以做到。更具便携性,持久性和易维护性。

Python tuto:

http://www.initd.org/pub/software/pysqlite/doc/usage-guide.html

答案 14 :(得分:0)

线性扫描很慢,但前缀树可能有点过分。保持单词排序并使用二进制搜索是一种快速而简单的妥协。

import bisect
words = sorted(map(str.strip, open('/usr/share/dict/words')))
def lookup(prefix):
    return words[bisect.bisect_left(words, prefix):bisect.bisect_right(words, prefix+'~')]

>>> lookup('abdicat')
['abdicate', 'abdication', 'abdicative', 'abdicator']

答案 15 :(得分:0)

如果将单词存储在.csv文件中,则可以使用pandas巧妙地解决此问题,并且在阅读完一次后,如果用户应该执行多个操作,则可以重用已经加载的数据框按会话搜索。

df = pd.read_csv('dictionary.csv')
matching_words = df[0].loc[df[0].str.startswith(user_entry)]