使用API和Python查找所有可能的字母组合
我正在尝试制作一个小型网页应用,用户只需输入他们手机号码的后四位数字,点击提交,然后就能看到可以用这四个数字在键盘上组合出的所有单词(如果有的话)。比如,如果用户输入了2287,他们会看到acts、bats、cats以及其他可以由a / b / c和a / b / c、t / u / v、p / q / r / s组合而成的单词。
我对网页应用和网页脚本还很陌生,但我已经弄明白了大部分步骤。现在我遇到的问题是:
创建所有可能的字母组合
找出哪些组合实际上是单词
我觉得可以用某种API来解决这些问题,但我不知道该去哪里找。如果我使用某种字典API,能否一次性输入所有可能的组合,还是说我得大约进行81次不同的API调用来检查每个组合是否是真正的单词。
显然,我在这方面还是个新手,但我想从这样简单的项目开始,逐步熟悉服务器端的网页脚本。如果可能的话,最好所有的工作都用Python来完成,因为这是我们在互联网应用课程中使用的语言,最开始用一种语言会更方便。无论如何,提前谢谢你们的帮助。
2 个回答
2
一种简单的方法是
import itertools
letters = ('','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz')
good_words = set(['wall','base','cats']) # etc
def allWords(s):
s = [int(ch) for ch in s.zfill(4)]
for word in itertools.product(letters[s[0]], letters[s[1]], letters[s[2]], letters[s[3]]):
word = ''.join(word)
if word in good_words:
yield word
words = list(allWords('2297'))
更有效的方法是先把所有好的单词整理成一个字典,字典里每个电话号码对应一个单词列表,然后只需要查找就可以了:
import string
import collections
class CodingError(Exception):
pass
class TelephoneWords(object):
numbers = {
'a': '2', 'b': '2', 'c': '2', 'd': '3',
'e': '3', 'f': '3', 'g': '4', 'h': '4',
'i': '4', 'j': '5', 'k': '5', 'l': '5',
'm': '6', 'n': '6', 'o': '6', 'p': '7',
'q': '7', 'r': '7', 's': '7', 't': '8',
'u': '8', 'v': '8', 'w': '9', 'x': '9',
'y': '9', 'z': '9', '0': '0', '1': '1',
'2': '2', '3': '3', '4': '4', '5': '5',
'6': '6', '7': '7', '8': '8', '9': '9'
}
wordlen = 4
def __init__(self, wordlist=None, fname=None):
super(TelephoneWords,self).__init__()
self.words = collections.defaultdict(list)
if wordlist:
self.addwords(wordlist)
if fname:
with open(fname) as inf:
filestr = ' '.join(inf.readlines()).replace(string.punctuation, ' ')
self.addwords(filestr.split())
def addwords(self, words):
_wordlen = TelephoneWords.wordlen
_words = self.words
_encode = self.encode
for word in words:
if len(word)==_wordlen:
word = word.lower()
try:
_words[_encode(word)].append(word)
except CodingError:
pass
def addword(self, word):
self.addwords((word,))
def encode(self, s):
_numbers = TelephoneWords.numbers
res = []
for ch in s:
try:
res.append(_numbers[ch])
except KeyError:
# no corresponding value found
raise CodingError("No value available for char '{0}'".format(ch))
return ''.join(res)
def seek(self, num):
s = str(num).strip().zfill(TelephoneWords.wordlen)
try:
return self.words[s]
except KeyError:
raise ValueError("No words found for '{0}'".format(s))
def find(self, num, onErr=None):
try:
return self.seek(num)
except ValueError:
return [] if onErr is None else onErr
def main():
tw = TelephoneWords(fname='four_letter_words.txt')
for word in tw.find('2287'):
print word
if __name__=="__main__":
main()
使用拼字游戏的单词列表,这样我得到了
acts
bats
baur
cats
caup
3
读取字典中的单词,只保留四个字母的单词,然后根据这四个字母的数字编码,把它们添加到一个默认的字典中,字典的值是一个列表。当用户输入数字时,给他们这个数字对应的单词列表,或者说“这个数字没有单词”。
import itertools
letters = ('',' ', 'abc','def','ghi','jkl','mno','pqrs','tuv','wxyz')
reverse_dict = dict((str(ind), group)
for ind,group in enumerate(letters)
for c in group
if letters)
print reverse_dict
end_nums = '3965'
print end_nums, 'can produce', tuple(''.join(w) for w in itertools.product(*map(reverse_dict.get, end_nums)))
word = 'word'
print('%r = %s' % (word,''.join(key for c in word for key, item in reverse_dict.items() if c in item)))