Алгоритм для получения списка всех слов, которые являются анаграммами всех подстрок (царапает)?

Добро пожаловать в кодирование! Это - аккуратная попытка попытки решить проблему. Чтобы заставить это работать, необходимо удостовериться, что вызвали основную функцию в нижней части кода (функции не будут работать, если Вы не скажете им!

def main():
    number=int(input("Please enter an integer between 0 and 127: "))
    if number>127 or number<0 :
        print("I'm sorry, that is not an acceptable value. Please try again")
        main()
    elif number<=127 and number>=0 :
        print("WIP")
    else:
        print("I'm sorry, something went wrong. Please try again and be sure to enter an integer between 0 and 127.")
        main()

main()

, В то время как это будет работать, это могло бы вызвать проблемы в будущем. Я предложил бы использовать while цикл для этого:

while True:
    number=int(input("Please enter an integer between 0 and 127: "))
    if number>127 or number<0 :
        print("I'm sorry, that is not an acceptable value. Please try again")
    elif number<=127 and number>=0 :
        print("WIP")
        break;
    else:
        print("I'm sorry, something went wrong. Please try again and be sure to enter an integer between 0 and 127.")

while цикл будет работать как условие, которое Вы даете ему, true. Вы можете break из цикла рано... хорошо, с помощью break ключевое слово.

12
задан casperOne 4 May 2012 в 21:50
поделиться

7 ответов

Структура, используемая для хранения вашего словаря действительных записей, будет иметь огромное влияние на эффективность. Организуйте его как дерево, где корнем является пустая строка в единственном числе, нулевая буква. Каждый дочерний элемент root - это одна первая буква возможного слова, потомки тех, которые являются второй буквой возможного слова и т. Д., С каждым узлом, отмеченным в отношении того, действительно ли он образует слово или нет.

Ваша функция тестера будет рекурсивным. Он начинается с нулевых букв, обнаруживает из дерева допустимых записей, что "" не является словом, но у него есть дочерние элементы, поэтому вы вызываете свой тестер рекурсивно, добавляя начальное слово (без букв) с каждой доступной оставшейся буквой из вашего входная строка (которая на тот момент все они). Проверьте каждую однобуквенную запись в дереве, если она допустима, сделайте заметку; если дети, повторно вызвать функцию тестера, добавив каждую из оставшихся доступных букв и т. д.

Так, например, если ваша входная строка - "helloworld", вы собираетесь сначала вызвать свою рекурсивную функцию тестера с помощью "", передав оставшиеся доступные буквы "helloworld" как 2-й параметр. Функция видит, что «» - это не слово, но дочерний элемент «h» существует. Таким образом, он называет себя с помощью «h» и «elloworld». Функция видит, что «h» - это не слово, но дочерний «e» существует. Таким образом, он называет себя «он» и «lloworld». Функция видит, что буква «е» помечена, поэтому «он» - это слово, обратите внимание. Кроме того, существует дочерний элемент «l», поэтому следующий вызов - «hel» с «loworld». Затем он найдет "ад", затем "привет",

14
ответ дан 2 December 2019 в 04:34
поделиться

Я не мог устоять перед своей собственной реализацией. Он создает словарь, сортируя все буквы по алфавиту и сопоставляя их со словами, которые могут быть созданы из них. Это операция запуска O (n), которая избавляет от необходимости находить все перестановки. Вы можете реализовать словарь как дерево на другом языке, чтобы добиться более быстрого ускорения.

Команда «getAnagrams» также является операцией O (n), которая ищет каждое слово в словаре, чтобы увидеть, является ли оно подмножеством поиска. Выполнение getAnagrams ("радиотелеграфно") "(слово из 20 букв) заняло на моем ноутбуке примерно 1 секунду и вернуло 1496 анаграмм.

# Using the 38617 word dictionary at 
# http://www.cs.umd.edu/class/fall2008/cmsc433/p5/Usr.Dict.Words.txt
# Usage: getAnagrams("helloworld")

def containsLetters(subword, word):
    wordlen = len(word)
    subwordlen = len(subword)

    if subwordlen > wordlen:
        return False

    word = list(word)
    for c in subword:
        try:
            index = word.index(c)
        except ValueError:
            return False
        word.pop(index)
    return True

def getAnagrams(word):
    output = []
    for key in mydict.iterkeys():
        if containsLetters(key, word):
            output.extend(mydict[key])

    output.sort(key=len)
    return output

f = open("dict.txt")
wordlist = f.readlines()
f.close()

mydict = {}
for word in wordlist:
    word = word.rstrip()
    temp = list(word)
    temp.sort()
    letters = ''.join(temp)

    if letters in mydict:
        mydict[letters].append(word)
    else:
        mydict[letters] = [word]

Пример выполнения:

>>> getAnagrams("helloworld")
>>> ['do', 'he', 'we', 're', 'oh', 'or', 'row', 'hew', 'her', 'hoe', 'woo', 'red', 'dew', 'led', 'doe', 'ode', 'low', 'owl', 'rod', 'old', 'how', 'who', 'rho', 'ore', 'roe', 'owe', 'woe', 'hero', 'wood', 'door', 'odor', 'hold', 'well', 'owed', 'dell', 'dole', 'lewd', 'weld', 'doer', 'redo', 'rode', 'howl', 'hole', 'hell', 'drew', 'word', 'roll', 'wore', 'wool','herd', 'held', 'lore', 'role', 'lord', 'doll', 'hood', 'whore', 'rowed', 'wooed', 'whorl', 'world', 'older', 'dowel', 'horde', 'droll', 'drool', 'dwell', 'holed', 'lower', 'hello', 'wooer', 'rodeo', 'whole', 'hollow', 'howler', 'rolled', 'howled', 'holder', 'hollowed']
9
ответ дан 2 December 2019 в 04:34
поделиться

Нужная структура данных называется Направленный ациклический граф слов (dawg) , и он описан Эндрю Аппелем и Гаем Якобсеном в их статье «Самый быстрый в мире скрэббл» Программа », которую, к сожалению, они решили не предоставлять бесплатно в Интернете. Членство в ACM или университетская библиотека предоставят его вам.

Я реализовал эту структуру данных как минимум на двух языках - это просто, легко реализовать и очень, очень быстро.

6
ответ дан 2 December 2019 в 04:34
поделиться

Простой подход состоит в том, чтобы сгенерировать все «подстроки» и для каждой из них проверить, является ли она элементом набора допустимых слов. Например, в Python 2.6:

import itertools
import urllib

def words():
  f = urllib.urlopen(
    'http://www.cs.umd.edu/class/fall2008/cmsc433/p5/Usr.Dict.Words.txt')
  allwords = set(w[:-1] for w in f)
  f.close()
  return allwords

def substrings(s):
  for i in range(2, len(s)+1):
    for p in itertools.permutations(s, i):
      yield ''.join(p)

def main():
  w = words()
  print '%d words' % len(w)
  ss = set(substrings('weep'))
  print '%d substrings' % len(ss)
  good = ss & w
  print '%d good ones' % len(good)
  sgood = sorted(good, key=lambda w:(len(w), w))
  for aword in sgood:
    print aword

main()

выдаст:

38617 words
31 substrings
5 good ones
we
ewe
pew
wee
weep

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

2
ответ дан 2 December 2019 в 04:34
поделиться

Вам нужна реализация набора мощности .

Также посмотрите блог Эрика Липпартса, он писал об этой самой вещи недавно

РЕДАКТИРОВАТЬ:

Вот реализация, которую я написал для получения набора мощности из заданной строки .. .

private IEnumerable<string> GetPowerSet(string letters)
{
  char[] letterArray = letters.ToCharArray();
  for (int i = 0; i < Math.Pow(2.0, letterArray.Length); i++)
  {
    StringBuilder sb = new StringBuilder();
    for (int j = 0; j < letterArray.Length; j++)
    {
      int pos = Convert.ToInt32(Math.Pow(2.0, j));
      if ((pos & i) == pos)
      {
        sb.Append(letterArray[j]);
      }
    }
    yield return new string(sb.ToString().ToCharArray().OrderBy(c => c).ToArray());
  }
}

Эта функция дает мне наборы параметров символов, которые составляют переданную строку, затем я могу использовать их как ключи в словаре анаграмм ...

Dictionary<string,IEnumerable<string>>

Я создал свой словарь анаграмм вот так ... ( есть, вероятно, более эффективные способы, но это было просто и достаточно быстро со списком слов турнира по скрэбл-турниру)

wordlist = (from s in fileText.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
                let k = new string(s.ToCharArray().OrderBy(c => c).ToArray())
                group s by k).ToDictionary(o => o.Key, sl => sl.Select(a => a));
2
ответ дан 2 December 2019 в 04:34
поделиться

Как Тим Дж. , Эрик Липперт в блогах, где первое, что приходит мне в голову. Я хотел добавить, что он написал продолжение о способах повышения эффективности своей первой попытки.

0
ответ дан 2 December 2019 в 04:34
поделиться
  • Сохраняйте семантику. Используйте полные, простые (желательно английские) слова. Не пытайтесь придумывать что-то необычное или техническое и не описывайте, что это - мы это знаем. Опишите, что он делает . Описание цели добавляет информационную ценность.

  • Ничего не сокращайте! BW_RCB01_SW что-то значил для команды, которая много лет назад занималась нашим CSS, но сейчас это ничего не значит для меня, и мне приходится работать в обратном направлении, чтобы попытаться перевести то, что BW_RCB01_SW соответствует для моих целей, и либо запомните этот перевод, либо запишите его где-нибудь. Лучше? черно-белый-boxtype1-bottomleft . Он длиннее, но также не требует розеттского камня.

  • Используйте строчные буквы и символы подчеркивания или дефисы. Я предпочитаю дефисы, но это ' s полностью предпочтение. Не должно быть препятствий для использования дефисов, поскольку они не зарезервированы в CSS или HTML, а идентификаторы обрабатываются как буквальные строки на всех других языках. Строчные буквы - это весь опыт - слишком много часов потрачено на размышления, какого черта этот стиль не применим. pageContainerLeft не то же самое, что pageContainerleft .

  • Определите точно , что это за элемент, но не более того. Серьезно подумайте о каждой части информации, которую вы вкладываете в имя, и о том, необходимо ли это. В вашем примере - вам нужно, чтобы знал, что это флажок рядом с идентификатором? Вряд ли. Вы уже знаете, о каком элементе вы говорите, потому что это уникальный идентификатор, и вам все равно придется кодировать этот элемент.

0
ответ дан 2 December 2019 в 04:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: