查找模式中的所有匹配单词

时间:2013-05-26 19:21:11

标签: algorithm

我收到一个字,但有些字母丢失了。我应该将所有可能匹配的单词返回到此模式。 例如,我收到__erf_ow我需要返回overflow

如果我得到模式_a_,我需要返回:cat bag ...所有长度为3且第二个字母为

的字词

给出所有单词的字典 - 存储它的最佳方法是什么,或者使用哪种算法来快速找到所有相关单词?

修改:我认为最好是指运行时间。我不在乎花费多少时间存储数据(只要它完成),但我想快速回答。显而易见的答案是哈希表,但这个表格会很大。

4 个答案:

答案 0 :(得分:1)

'最佳'取决于你拥有的资源。

以下是我要做的事情:

  1. 为每个字长存储单独的字典。
  2. 我认为您的搜索不区分大小写! 如果字符a..z出现在字中,则为每个字存储32位值,其中设置位0到25。 将单词存储在Map<Integer, List<String>>中(键是32位值,值是此键的所有单词的列表)
  3. 如何搜索:

    1. 带有想要长度的字典
    2. 为您的模式创建32位值。
    3. 迭代Map的所有键,并检查键的按位和模式的32位值是否等于模式的32位值。如果不是这不能匹配。 如果通过此检查,则仅仅匹配是不够的,因为它不处理字符的顺序或者如果出现多于1的字符。但检查速度非常快,不需要查看单词的每个字符。

    4. 迭代Map中的列表,并通过将列表中每个单词的字符与您的模式进行比较来检查它们与您的模式的真实匹配。

    5. 实施例: 字母对于3个字母的单词: the,cat,bag,nor,ega,atc,ron;

      -> Hashvalues
           00000000000010000000000010010000   the
           00000000000010000000000000000101   cat, atc
           00000000000000000000000001000011   bag
           00000000000000100110000000000000   nor, ron
           00000000000000000000000001010001   age, ega
      
       Value for pattern _a_ is 00000000000000000000000000000001
      
      Step 3 returns that the keys 
            00000000000010000000000000000101,  
            00000000000000000000000001000011 and 
            00000000000000000000000001010001 are candidates for matches.
      
      
      
      Step 4 returns: 'cat' and 'bag'
      

答案 1 :(得分:0)

如果您使用HashMap,在其中按字母排序,它会显得更小?

 ArrayList<HashMap<Character, ArrayList<String>>> dictionary;

HashMap的第一个字符是指示符,该字母是单词的一部分。

第一个ArrayList可以存储每个单词,List的索引可以显示,哪个Character存储在哪里。所以你可以用-a-:dictionary.get(2).get(a)来获取单词。结果:每个单词都带有第二个位置。

第二个ArrayList存储单词。

答案 2 :(得分:0)

Levenshtein distance可以帮到你。还有其他字符串相似度函数。根据您的约束,您可以使用自己的距离函数。此外,换能器是个好主意。 Here这是一个良好的开端,再次,你必须努力使这适合你自己的问题。

如果Dukeling在下面说你需要削减你的运行时间,那么你可以使用一些紧凑的数据结构(如小波树)来做这件事,并在节点上进行访问/范围/排名查询(最好的情况是log2字母表的大小),但同样,你必须使它适合你自己的问题。

答案 3 :(得分:0)

如果你不介意非常无效的内存,你可以在哈希表中存储单词集 - 其中键是模式(我相信这应该是获取数据的最快算法之一):

trees = {}


def init(filename):
    with open(filename) as f:
        for word in f:
            word = word.strip()
            s = trees.get((len(word),0,''), set())
            s.add(word)
            trees[(len(word),0,'')] = s
            for i,c in enumerate(word):
                s = trees.get((len(word),i,c), set())
                s.add(word)
                trees[(len(word),i,c)] = s


def words_for_pattern(pattern):
    pattern = pattern.lower()
    words = trees[(len(pattern),0,'')]
    for i, c in enumerate(pattern):
        if c in "abcddefghijklmnopqrstuvwxyz":
            words = words.intersection(trees[(len(pattern),i,c)])

    return words

if __name__ == '__main__':
    init('english-words.20')
    while (True):
        pattern = raw_input("Enter pattern: ")
        print words_for_pattern(pattern)


 Enter pattern: **ll*
>>> set(['balls', 'rolls', 'hills', 'cells', 'polls', 'jelly', 'bills', 'pills', 'jolly', 'halls', 'bells'])

此处trees是一个地图,其中键是3元组:(word-length, character index, character),每个键的值是一组长度为word-lengthcharacter的所有单词在character index地方。此外,还有一些特殊键包含一定长度的所有单词。

获取模式的单词时,我会与模式中每个非空白字符的单词组相交。