Как я разрешаю “осуществление” Строки над заголовком Склепа, предложенное в “Программировании проблем (Руководство по обучению Конкурса Программирования)”?

"Программирование проблем (Руководство по обучению Конкурса Программирования)" является, вероятно, одной из самой хорошей книги упражнений по алгоритмам. Я разрешил первые 11 упражнений, но теперь я застреваю с "проблемой" Строки над заголовком Склепа:

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

Ваша задача состоит в том, чтобы дешифровать несколько закодированных строк текста, предположив, что каждая строка использует различный набор замен, и что все слова в дешифрованном тексте из словаря известных слов.

Вход
Вход состоит из строки, содержащей целое число n, сопровождаемый n строчными словами, один на строку, в алфавитном порядке. Эти n слова сочиняют словарь слов, которые могут появиться в дешифрованном тексте.
После словаря несколько строк входа. Каждая строка шифруется, как описано выше.

В словаре существует не больше, чем 1 000 слов. Никакое слово не превышает 16 букв. Зашифрованные строки содержат только строчные буквы и пробелы и не превышают 80 символов в длине.

Вывод
Дешифруйте каждую строку и распечатайте ее к стандартному выводу. Если будет несколько решений, то любой сделает.
Если нет никакого решения, замените каждую букву алфавита звездочкой.

Демонстрационный вход 6
и
dick
jane
затяжка
пятно
yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd

Демонстрационный вывод
dick и jane и затяжка и пятно и yertle...

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

PS: Это не связанная домашняя работа, я просто пытаюсь улучшить свои полные навыки.

14
задан kiamlaluno 17 October 2011 в 10:03
поделиться

3 ответа

Похоже, что данные экземпляра объекта повреждены в памяти.

Сам VMT не повреждается, FWIW: VMT (обычно) хранится в исполняемом файле, а сопоставляемые с ним страницы доступны только для чтения. Скорее, как говорит V.K., похоже, что первое поле данных экземпляра в вашем случае было перезаписано 32-битным целым числом со значением 1. Это достаточно просто проверить: проверить данные экземпляра объекта, чей вызов метода не удался, и убедиться, что первое dword - 00000001.

Если это действительно указатель VMT в данных экземпляра, которые повреждаются, вот как бы я нашел код, который его повреждает:

  1. Убедитесь, что существует автоматизированный способ воспроизведения проблемы, которая не требует пользовательского ввода. Проблема может быть воспроизводимой только на одной машине без перезагрузки между воспроизведениями из-за того, как Windows может выбрать размещение памяти.

  2. Воспроизведите проблему и запишите адрес данных экземпляра, память которого повреждена.

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

  4. Теперь, перейдя в третий прогон, поместите 4-байтовую точку останова данных в раздел памяти, указанный двумя предыдущими прогонами. Этот пункт заключается в разрыве каждой модификации этой памяти. По крайней мере один разрыв должен быть вызовом Tobject.InitInstance, который заполняет указатель VMT; могут быть другие, связанные с конструкцией экземпляра, такие как в распределителе памяти; и в худшем случае соответствующие данные экземпляра могут быть повторно использованы в памяти из предыдущих экземпляров. Чтобы сократить количество необходимых шагов, запишите в журнал точек останова данные стек вызовов, но не прерывать его. Проверяя стеки вызовов после сбоя виртуального вызова, можно найти неверную запись.

-121--4605624-

В IE8 с использованием .Net впервые устанавливается значение iframe.src , но установка iframe.src во второй раз не приводит к повышению page _ load iframed page. Для решения этой проблемы используется iframe.contentDocument.location.href = «NewUrl.htm» .

Обнаружьте его при использовании jQuery thickBox и попытайтесь снова открыть ту же страницу в iframe thickbox. Затем она только что показала предыдущую страницу, которая была открыта.

-121--595154-

KeyArray будет содержать таблицу замены.

  • Начните с пустого KeyArray, это версия 0

  • Сопоставьте самое длинное зашифрованное слово с самым длинным словарным словом и добавьте в KeyArray (если есть два самых длинных, выберите любой), это версия 1.

  • Расшифруйте некоторые буквы следующего самого длинного зашифрованного слова.

  • Проверьте, совпадают ли расшифрованные буквы и буквы. позиция в любом словарном слове одинаковой длины.
  • Если нет совпадений, вернитесь к версии 0 и попробуйте другое слово.
  • Если некоторые буквы совпадают, добавьте остальные буквы в KeyArray, это версия 2.

  • Расшифруйте некоторые буквы следующего самого длинного зашифрованного слова.

  • Проверьте, совпадают ли расшифрованные буквы и буквы. позиция в любом словарном слове.
  • Если нет совпадений, вернитесь к версии 1 и попробуйте другое слово
  • Если некоторые буквы совпадают, добавьте остальные буквы в KeyArray, это версия 3.

Повторяйте до тех пор, пока все слова не будут расшифрованы.

Если в версии 0 ни одно из самых длинных слов не создает частичную расшифровку в более короткие слова, очень вероятно, нет решения.

9
ответ дан 1 December 2019 в 14:32
поделиться

Незначительная оптимизация может быть выполнена путем перечисления возможностей перед выполнением обратного отслеживания. В Python:

dictionary = ['and', 'dick', 'jane', 'puff', 'spot', 'yertle']
line = ['bjvg', 'xsb', 'hxsn', 'xsb', 'qymm', 'xsb', 'rqat', 'xsb', 'pnetfn']

# ------------------------------------

import collections

words_of_length = collections.defaultdict(list)

for word in dictionary:
  words_of_length[len(word)].append(word)

possibilities = collections.defaultdict(set)
certainities = {}

for word in line:
    length = len(word)
    for i, letter in enumerate(word):
        if len(words_of_length[length]) == 1:
            match = words_of_length[length][0]
            certainities[letter] = match[i]
        else:
            for match in words_of_length[length]:
              possibilities[letter].add(match[i])

for letter in certainities.itervalues():
    for k in possibilities:
        possibilities[k].discard(letter)

for i, j in certainities.iteritems():
    possibilities[i] = set([j])

# ------------------------------------

import pprint
pprint.pprint(dict(possibilities))

Output:

{'a': set(['c', 'f', 'o']),
 'b': set(['d']),
 'e': set(['r']),
 'f': set(['l']),
 'g': set(['f', 'k']),
 'h': set(['j', 'p', 's']),
 'j': set(['i', 'p', 'u']),
 'm': set(['c', 'f', 'k', 'o']),
 'n': set(['e']),
 'p': set(['y']),
 'q': set(['i', 'j', 'p', 's', 'u']),
 'r': set(['j', 'p', 's']),
 's': set(['n']),
 't': set(['t']),
 'v': set(['c', 'f', 'o']),
 'x': set(['a']),
 'y': set(['i', 'p', 'u'])}

Если у вас есть некоторые одноэлементные возможности, вы можете исключить их из ввода и повторно запустить алгоритм.

EDIT: Переключение на набор вместо списка и добавление кода печати.

3
ответ дан 1 December 2019 в 14:32
поделиться

Еще одна возможная оптимизация, если у вас есть «достаточно», чтобы иметь значение «достаточно», чтобы иметь дело, и вы знаете язык текста, вы можете использовать буквенные частоты (см.: http://en.wikipedia.org/wiki/letter_frequency ). Это, конечно, очень приблизительный подход при работе с 6/7 слов, но будет самым быстрым способом, если у вас есть несколько страниц для декодирования.

Отредактируйте: о решении Max, вы можете попытаться извлечь некоторые характеристики слова тоже, такие как повторяющиеся буквы. Очевидно, что замечает, что слойки в словаре и Qymm в зашифрованном тексте являются единственными четырем буквенными словами, заканчивающимися с двойной буквой, дает прямой ответ на 3 из букв. В более сложных сценариях вы должны уметь сузить возможности для каждой парольной пары.

0
ответ дан 1 December 2019 в 14:32
поделиться
Другие вопросы по тегам:

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