【发布时间】:2011-04-02 12:10:43
【问题描述】:
我正在研究 Allen Downey 的How To Think Like A Computer Scientist,并且我已经编写了我认为对练习 10.10 功能正确的解决方案。但它只花了 10 多个小时 (!) 来运行,所以我想知道我是否遗漏了一些非常明显且有用的优化。
这是练习:
“如果从每个单词中交替的字母组成一个新单词,则两个单词 'interlock'。例如,'shoe' 和 'cold' 互锁以形成 'schooled'。编写一个程序来查找所有互锁的单词对。提示: 不要枚举所有对!"
(对于这些单词列表问题,Downey 提供了一个包含 113809 个单词的文件。我们可以假设这些单词在一个列表中,列表中每个项目一个单词。)
这是我的解决方案:
from bisect import bisect_left
def index(lst, target):
"""If target is in list, returns the index of target; otherwise returns None"""
i = bisect_left(lst, target)
if i != len(lst) and lst[i] == target:
return i
else:
return None
def interlock(str1, str2):
"Takes two strings of equal length and 'interlocks' them."
if len(str1) == len(str2):
lst1 = list(str1)
lst2 = list(str2)
result = []
for i in range(len(lst1)):
result.append(lst1[i])
result.append(lst2[i])
return ''.join(result)
else:
return None
def interlockings(word_lst):
"""Checks each pair of equal-length words to see if their interlocking is a word; prints each successful pair and the total number of successful pairs."""
total = 0
for i in range(1, 12): # 12 because max word length is 22
# to shorten the loops, get a sublist of words of equal length
sub_lst = filter(lambda(x): len(x) == i, word_lst)
for word1 in sub_lst[:-1]:
for word2 in sub_lst[sub_lst.index(word1)+1:]: # pair word1 only with words that come after word1
word1word2 = interlock(word1, word2) # interlock word1 with word2
word2word1 = interlock(word2, word1) # interlock word2 with word1
if index(lst, word1word2): # check to see if word1word2 is actually a word
total += 1
print "Word 1: %s, Word 2: %s, Interlock: %s" % (word1, word2, word1word2)
if index(lst, word2word1): # check to see if word2word1 is actually a word
total += 1
print "Word 2, %s, Word 1: %s, Interlock: %s" % (word2, word1, word2word1)
print "Total interlockings: ", total
打印语句不是问题;我的程序只找到了 652 对这样的对。问题是嵌套循环,对吧?我的意思是,即使我正在循环仅包含相同长度的单词的列表,也有(例如)21727 个长度为 7 的单词,这意味着我的程序必须检查超过 4 亿个“互锁”以查看它们是否'是实际的单词——这只是长度为 7 的单词。
同样,这段代码运行了 10 个小时(如果您好奇的话,没有发现长度为 5 或更大的单词对)。有没有更好的方法来解决这个问题?
在此先感谢您提供任何和所有见解。我知道“过早的优化是万恶之源”——也许我已经落入了那个陷阱——但总的来说,虽然我通常可以编写正确运行的代码,但我经常难以编写运行良好的代码。
【问题讨论】:
-
下面的答案很有意义,但是如果您尝试分析此代码以识别实际上使其变慢的原因,我很感兴趣?尝试加速的其他有用的事情是简单地通过 Psyco 或 PyPy 运行它。
-
@Glenjamin:我没有分析代码,因为我不知道如何。您能否提供一些说明如何执行此操作的文档的链接?谢谢!
-
docs.python.org/library/profile.html 解释得比我好得多 :) 简短版:
python -m cProfile myscript.py
标签: python