Поиск всех возможных комбинаций букв с использованием API и Python - PullRequest
0 голосов
/ 23 марта 2011

Я пытаюсь собрать небольшое веб-приложение, в котором пользователи вводят последние 4 цифры своего номера телефона, нажимают кнопку Отправить, а затем отображаются все слова (если таковые имеются), которые можно сделать на клавиатуре с помощью их4 номера.Поэтому, если пользователь вводит « 2287 », ему показывается « акты » « летучие мыши » « кошки » и любые другие слова, которые могутбыть изготовлены из комбинации " a / b / c " и " a / b / c"и" t / u / v"и" p / q / r / s".

Я новичок в веб-приложениях и веб-сценариях, но я выяснил, как выполнить большинство шагов.У меня проблемы:

  1. Создание всех возможных комбинаций букв

  2. Выяснение, какие комбинации на самом деле являются словами

Я думаю, что вы могли бы сделать это с помощью API, но я не знаю, где искать что-то подобное.Если бы я использовал какой-то словарь API-интерфейса словаря, я мог бы ввести все возможные комбинации одновременно или мне пришлось бы (примерно) сделать 81 вызов API, чтобы проверить, является ли каждая комбинация реальным словом.

I 'Я, очевидно, довольно большой нуб, когда дело доходит до таких вещей, но я пытаюсь начать с чего-то простого, как это, чтобы попытаться познакомиться с серверными веб-скриптами.Кроме того, если это вообще возможно, было бы замечательно, если бы я все делал на Python, так как это язык, который мы используем в моем классе интернет-приложений, и было бы целесообразно сначала придерживаться только одного языка.В любом случае, заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 23 марта 2011

Прочитайте словарь и сохраните только 4-буквенные слова, добавьте их в defaultdict (список) с помощью числового кода из четырех букв, когда пользовательские вводы для чисел дают им готовый список для этого номера или говорят «Нет слов для этого номера» .

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)))
2 голосов
/ 23 марта 2011

Наивный подход был бы

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
...