我有一个基本字符串和一个包含某些单词的字典。我想使用字典中的单词找到基本字符串的所有可能的字谜。
例如:
base_string = 'Oscar Wilde'
words = {1: 'sidecar', 2: 'owl', 3: 'low', 4: 'acid', 5: 'bread', 6: 'slower'}
现在我想看看我可以用字典中的单词制作多少个不同的字谜。期望的输出将是'sidecar owl','sidecar low','acid slow'。
我将字符串转换为列表,如下所示:
letters = ['o', 's', 'c', 'a', 'r', 'w', 'i', 'l', 'd', 'e']
我希望我的代码能够检查字典中的每个单词组合。我有一个计数器,可以计算尝试过的组合数量。
anagrams = []
counter = 0
for i in range(1, len(words)+1):
anagram = ''
for i in range(i+1, len(words)+1):
if contain(letters, words[i]): #if word is contained in the base string
for i in words[i]: #remove each letter of the word from the list of letters of the base string
letters.remove(i)
anagram += words[i] + ' '
if len(letters) >= 1: #if all the letters are not used, it's not an anagram
counter += 1
if len(letters) == 0: #if all the letters are used, it's an anagram
anagrams.append(anagram)
print anagrams
def contain(list1, list2):
counter1 = Counter(list1)
counter2 = Counter(list2)
for k in counter2:
if counter2[k] != counter1.get(k):
return False
return True
findanagram()
我得到了anagram + = words [i] +''
的KeyError我希望自己能够很好地解释自己。
答案 0 :(得分:0)
我个人推荐hege的解决方案。它简单明了,直截了当。但是,如果您计划使用大型字典并多次重复此过程,则可能会对更快的方法感兴趣。
这个想法是将每个字母与素数相关联,即a = 2,b = 3,c = 5等。得到数字25的唯一方法是在你的单词中加上字母c两次。通过将单词中的所有字母相乘,您可以获得其ID号。当然,该单词的任何字谜也会产生相同的id。
所以,你所要做的就是检查单词A和B的id的乘积是否等于你感兴趣的单词的id。
from itertools import combinations
from string import ascii_lowercase as alphabet
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101]
letter_id = dict(zip(alphabet, primes))
def get_word_id(word):
product = 1
for letter in word:
product *= letter_id[letter]
return product
words = ['sidecar', 'owl', 'low', 'acid', 'bread', 'slower']
dictionary = {}
for w in words:
dictionary[w] = get_word_id(w)
base_string = 'Oscar Wilde'
for comb in combinations(words, 2):
comb_id = 1
for word in comb:
comb_id *= dictionary[word]
if get_word_id(base_string.replace(' ', '').lower()) == comb_id:
print comb
正如我在hege的回答中所评论的那样,如果你对超过对的兴趣感兴趣,你可以推广这样的组合
for no_of_words in xrange(1, len(words)+1):
for comb in combinations(words, no_of_words):
...
答案 1 :(得分:-1)
这是最容易但最有效的方法。它会搜索两个字的字谜:
from itertools import combinations
from collections import Counter
name = 'Oscar Wilde'
words = ['sidecar', 'owl', 'low', 'acid', 'bread', 'slower']
letter_counter = Counter(name.replace(' ', '').lower())
for ws in combinations(words, 2):
if Counter(''.join(ws)) == letter_counter:
print(' '.join(ws))
它基本上与你的预期相同,但是以更加py的方式。
您的实施存在一些问题:
contain('a', 'aa')
带来错误,因为它会通过相等来检查出现的字母数。i
索引变量。range(1, len(words) + 1)
),但python数组从0开始(range(0, len(words))
)