本書中的exercise 9.3要求讀者找到排除this file中最小字數的5個禁止字母的組合。在「Think Python:如何像計算機科學家那樣思考」練習9.3中,是否有更好的算法
下面是我對第一部分的解決方案,我認爲這是對他們
# if the word contain any letter in letters, return True,
# otherwise return False
def contain(word, letters):
for letter in letters:
if letter in word:
return True
return False
# return the number of words contain any letter in letters
def ncont(words, letters):
count = 0
for word in words:
if contain(word, letters):
count += 1
return count
但對於上面的問題,我只能認爲蠻力算法,就是想盡一切沒問題有可能的組合,正好有26!/5! = 65780種組合,下面是執行:
def get_lset(nlt, alphabet, cur_set):
global min_n, min_set
# when get enough letters
if nlt <= 0:
cur_n = ncont(words, ''.join(cur_set))
if min_n == -1 or cur_n < min_n:
min_n = cur_n
min_set = cur_set.copy()
print(''.join(cur_set), cur_n, ' *->', min_n, ''.join(min_set))
# otherwise find the result letters in a recursive way
else:
cur_set.append(None)
for i in range(len(alphabet)):
cur_set[-1] = alphabet[i]
get_lset(nlt-1, alphabet[i+1:], cur_set)
cur_set.pop()
,然後調用這樣上面的函數:
if __name__ == '__main__':
min_n = -1
min_set = []
with open('words.txt', 'r') as fin:
words = [line.strip() for line in fin]
get_lset(5, list(string.ascii_lowercase), [])
print(min_set, min_n)
但這種方法是很慢的,我想知道的是有這個問題的一個更好的算法?任何建議都會很好!
非常感謝,這是一個很好的例子,它展示了python簡潔的強大功能,並且功能變得比原始實現更快。你有沒有對第二部分的建議,找到可以得到最少字數的5個字母的集合?我認爲蠻力算法還不夠好 – zbtong
@zbtong:看我的更新 – Eric
這太棒了,函數式編程風格似乎是讓程序更具可讀性的好方法,非常感謝。 – zbtong