В Python: как я могу заставить свой код распечатать все возможные слова, которые я могу написать по буквам на основе введенных мной данных? - PullRequest
1 голос
/ 29 мая 2020

Думаю, я был близок к тому, чтобы понять, как распечатать все возможные слова на основе пользовательского ввода из моего заданного словаря. он основан на предположении, что пользовательский ввод - это «ART», поэтому возможные слова, которые у меня есть в моем словаре, - это ART, RAT, TART и TAR, но распечатываются только трехбуквенные комбинации. может кто-нибудь сказать мне, где я ошибаюсь? Спасибо!

Dictionary = ["tar","art","tart","rat"] #creates dictionary of set words
StoredLetters = input('input your word here: ') #allows the user to input any word
list(StoredLetters)

def characters(word):
    Dictionary = {}
    for i in word:
        Dictionary[i] = Dictionary.get(i, 0) + 1
    return Dictionary

def all_words(StoredLetters, wordSet):
    for word in StoredLetters:
        flag = 1
        words = characters(word)
        for key in words:
            if key not in wordSet:
                flag = 0
            else:
                if wordSet.count(key) != words[key]:
                    flag = 0
        if flag == 1:
            print(word)
if __name__ == "__main__":
    print(all_words(Dictionary, StoredLetters))

Ответы [ 3 ]

0 голосов
/ 29 мая 2020

Похоже, есть несколько вещей, которые могут этому способствовать.

  1. Вы меняете местами параметры всех слов def allwords(Dictionary, StoredLetters):, когда вызываете его в main allwords(StoredLetters, Dictionary). Без указания имени (найдите именованные параметры в python) вы замените ввод.

  2. В функции characters, похоже, вы сбрасываете словарную переменную. Попробуйте использовать уникальные имена при создании новых переменных. Это приводит к тому, что словарь слов, который вы установили вверху, очищается, когда characters(word) вызывается

0 голосов
/ 29 мая 2020

Во-первых, вы сбиваете с толку, когда имя вашей переменной StoredLetters также является именем одного из аргументов вашей all_words функции.

Во-вторых, вы фактически передаете StoredLetters, то есть art, в качестве 2-го аргумента функции, поэтому в функции это wordSet, а не StoredLetters!

Вы действительно должны сделать вещи более ясными, используя разные имена переменных , и сделать очевидным, что вы используете в качестве аргумента. words на самом деле не слова, это словарь с буквами в качестве ключей и сколько раз они появляются в качестве значений! Сделать код ясным и понятным имеет большое значение для облегчения отладки. У вас есть word, StoredLetters, wordSet, еще один аргумент StoredLetters, words = characters(word), который не выполняет ожидаемых действий. Все это может потребовать хорошей очистки.

Что касается функциональности, с art каждая буква появляется только один раз, поэтому для tart, который имеет t дважды, if wordSet.count(key) != words[key] будет оцениваться как True , и flag будет установлен на 0, и слово не будет напечатано.

Надеюсь, что это поможет, и удачного кодирования!

0 голосов
/ 29 мая 2020

Основываясь на последующих комментариях, правило состоит в том, что мы должны использовать все символы в целевом слове, но мы можем использовать каждый символ столько раз, сколько захотим.

Я бы установил поиск структуры данных "словаря" как Python dict, который отображает отсортированные уникальные символы как кортежи в каждом словарном слове в список фактических слов, которые могут быть сформированы из этих символов.

Далее я 'd обрабатывать поиск следующим образом:

  • Сортировать уникальные символы ввода пользователя (целевое слово) и индексировать в словаре, чтобы получить список слов, которые он мог бы составить. Использование set означает, что мы разрешаем повторение, а сортировка символов означает, что мы нормализуем все возможные перестановки этих букв.
  • Одно только приведенное выше может давать ложные срабатывания, поэтому мы фильтруем полученный список слов для удаления любые фактические слова результата, которые короче целевого слова. Это гарантирует, что мы правильно обрабатываем целевое слово, например "artt", и предотвращаем его совпадение с "art".

Код:

from collections import defaultdict

class Dictionary:
    def __init__(self, words):
        self.dictionary = defaultdict(list)

        for word in words:
            self.dictionary[tuple(sorted(set(word)))].append(word)

    def search(self, target):
        candidates = self.dictionary[tuple(sorted(set(target)))]
        return [x for x in candidates if len(x) >= len(target)]

if __name__ == "__main__":
    dictionary = Dictionary(["tar", "art", "tart", "rat"])
    tests = ["art", "artt", "ar", "arttt", "aret"]

    for test in tests:
        print(f"{test}\t=> {dictionary.search(test)}")

Вывод:

art     => ['tar', 'art', 'tart', 'rat']
artt    => ['tart']
ar      => []
arttt   => []
aret    => []

Проблемы в исходном коде были хорошо рассмотрены в других ответах. Logi c не кажется ясным, так как он сравнивает символы со словами, а имена переменных часто не соответствуют logi c, представленному кодом.

Можно использовать частотомер, но вы застрянете в итерации по словарю, и вам нужно будет проверить, что каждый счетчик символа в словарном слове больше, чем соответствующий счетчик в целевое слово. Я сомневаюсь, что предлагаемый мной код оптимален, но я думаю, что он должен быть намного быстрее, чем метод счетчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...