Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python算法-混合求解器_Python_Search_Optimization_Combinatorics - Fatal编程技术网

Python算法-混合求解器

Python算法-混合求解器,python,search,optimization,combinatorics,Python,Search,Optimization,Combinatorics,我正在编写一个程序,从python词典中查找一个混乱单词的所有可能组合 这是我写的。现在是O(n^2)时间。所以,我的问题是能让它更快吗? import sys dictfile = "dictionary.txt" def get_words(text): """ Return a list of dict words """ return text.split() def get_possible_words(words,jword): """ Return

我正在编写一个程序,从python词典中查找一个混乱单词的所有可能组合

这是我写的。现在是O(n^2)时间。所以,我的问题是能让它更快吗?

import sys

dictfile = "dictionary.txt"

def get_words(text):
    """ Return a list of dict words """
    return text.split()


def get_possible_words(words,jword):
    """ Return a list of possible solutions """
    possible_words = []
    jword_length = len(jword)
    for word in words:
        jumbled_word = jword
        if len(word) == jword_length:
            letters = list(word)
            for letter in letters:
                if jumbled_word.find(letter) != -1:
                    jumbled_word = jumbled_word.replace(letter,'',1)
            if not jumbled_word:
                possible_words.append(word)
    return possible_words       


if __name__ == '__main__':
    words = get_words(file(dictfile).read())
    if len(sys.argv) != 2:
        print "Incorrect Format. Type like"
        print "python %s <jumbled word>" % sys.argv[0]
        sys.exit()
    jumbled_word = sys.argv[1]
    words = get_possible_words(words,jumbled_word)
    print "possible words :"
    print '\n'.join(words)
导入系统 dictfile=“dictionary.txt” def get_单词(文本): “”“返回dict单词列表”“” 返回text.split() def获取可能的单词(单词,jword): “”“返回可能的解决方案列表”“” 可能的单词=[] jword_length=len(jword) 用文字表示: 乱七八糟的 如果len(word)=jword\u长度: 字母=列表(单词) 对于字母中的字母: 如果单词混淆,查找(字母)!=-1: 混乱的单词=混乱的单词。替换(字母,,,1) 如果没有混淆单词: 可能的单词。追加(单词) 返回可能的单词 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': words=获取单词(文件(dictfile.read()) 如果len(sys.argv)!=2: 打印“格式不正确。键入类似” 打印“python%s”%sys.argv[0] sys.exit() 混乱的单词=sys.argv[1] 单词=获取可能的单词(单词、混乱的单词) 打印“可能的单词:” 打印“\n”。加入(字)
我试图用ruby解决这个问题-


在中,通常快速解决字谜问题的方法是将已排序的字母映射到未排序的单词列表

有了这种结构,查找就可以立即快速:

def build_table(wordlist):
    table = {}
    for word in wordlist:
        key = ''.join(sorted(word))
        table.setdefault(key, []).append(word)
    return table

def lookup(jumble, table):
    key = ''.join(sorted(jumble))
    return table.get(key, [])

if __name__ == '__main__':

    # Build table
    with open('/usr/share/dict/words') as f:
        wordlist = f.read().lower().split()
    table = build_table(wordlist)

    # Solve some jumbles
    for jumble in ['tesb', 'amgaarn', 'lehsffu', 'tmirlohag']:
        print(lookup(jumble, table))
关于速度的说明:

  • lookup()代码是最快的部分
  • 为清晰起见,编写了较慢的buildtable()函数
  • 构建表是一次性操作
  • 如果您关心重复运行时的运行时间,则应将表缓存在文本文件中
文本文件格式(字母顺序优先,后跟匹配的单词):

对于预处理的anagram文件,使用subprocess对文件进行grep处理以获得合适的匹配字行就变得很简单了。这将提供非常快的运行时间(因为排序和匹配是预先计算的,而且grep非常快)

按如下方式构建预处理的字谜文件:

with open('/usr/share/dict/words') as f:
    wordlist = f.read().split()

table = {}
for word in wordlist:
    key = ''.join(sorted(word)).lower()
    table[key] = table.get(key, '') + ' ' + word

lines = ['%s%s\n' % t for t in table.iteritems()]
with open('anagrams.txt', 'w') as f:
    f.writelines(lines)

更改getwords以返回dict()。使每个键的值为true或1

导入itertools并使用itertools.compositions生成所有可能的anagramatic字符串 从“乱七八糟的词”

然后循环检查可能的字符串是否是dict中的键


如果您想要DIY算法解决方案,那么将字典加载到树中可能会“更好”,但我怀疑在现实世界中它是否会更快

考虑到程序没有问题,您可能会在codereview上获得更好的响应它是正确的。我已经测试过了。但是我想提高代码的效率。这个堆栈交换网站是专门为这些类型的问题开发的。这个问题似乎是离题的,因为它是关于代码审查的,因此属于on,我认为这个代码实际上是O(nmk),其中
n
是单词的长度
dict
m
是单词的平均长度,
k
是单词的长度。见鬼,如果
单词混乱,可能会有第四个循环。查找(字母)
通常是
!=-1
因为
替换
本身就是一个循环。重点是,此代码不是
O(n**2)
。我也尝试了此解决方案,但返回组合所需的时间为0.3秒。我写的东西只用了0.1秒。
with open('/usr/share/dict/words') as f:
    wordlist = f.read().split()

table = {}
for word in wordlist:
    key = ''.join(sorted(word)).lower()
    table[key] = table.get(key, '') + ' ' + word

lines = ['%s%s\n' % t for t in table.iteritems()]
with open('anagrams.txt', 'w') as f:
    f.writelines(lines)