"Программирование проблем (Руководство по обучению Конкурса Программирования)" является, вероятно, одной из самой хорошей книги упражнений по алгоритмам. Я разрешил первые 11 упражнений, но теперь я застреваю с "проблемой" Строки над заголовком Склепа:
Строка над заголовком склепа
Общий, но небезопасный метод шифрования текста должен переставить буквы алфавита. Другими словами, каждая буква алфавита последовательно заменяется в тексте некоторой другой буквой. Чтобы гарантировать, что шифрование обратимо, никакие две буквы не заменяются той же буквой.Ваша задача состоит в том, чтобы дешифровать несколько закодированных строк текста, предположив, что каждая строка использует различный набор замен, и что все слова в дешифрованном тексте из словаря известных слов.
Вход
Вход состоит из строки, содержащей целое число n, сопровождаемый n строчными словами, один на строку, в алфавитном порядке. Эти n слова сочиняют словарь слов, которые могут появиться в дешифрованном тексте.
После словаря несколько строк входа. Каждая строка шифруется, как описано выше.В словаре существует не больше, чем 1 000 слов. Никакое слово не превышает 16 букв. Зашифрованные строки содержат только строчные буквы и пробелы и не превышают 80 символов в длине.
Вывод
Дешифруйте каждую строку и распечатайте ее к стандартному выводу. Если будет несколько решений, то любой сделает.
Если нет никакого решения, замените каждую букву алфавита звездочкой.Демонстрационный вход 6
и
dick
jane
затяжка
пятно
yertlebjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc ddddddДемонстрационный вывод
dick и jane и затяжка и пятно и yertle...
Что стратегия должна я для взятия для разрешения этого осуществления? Я думал к классическому и жестокому решению для отслеживания в обратном порядке, но я пробую, избегают этого, пока я не нахожу что-то более интеллектуальным.
PS: Это не связанная домашняя работа, я просто пытаюсь улучшить свои полные навыки.
Похоже, что данные экземпляра объекта повреждены в памяти.
Сам VMT не повреждается, FWIW: VMT (обычно) хранится в исполняемом файле, а сопоставляемые с ним страницы доступны только для чтения. Скорее, как говорит V.K., похоже, что первое поле данных экземпляра в вашем случае было перезаписано 32-битным целым числом со значением 1. Это достаточно просто проверить: проверить данные экземпляра объекта, чей вызов метода не удался, и убедиться, что первое dword - 00000001.
Если это действительно указатель VMT в данных экземпляра, которые повреждаются, вот как бы я нашел код, который его повреждает:
Убедитесь, что существует автоматизированный способ воспроизведения проблемы, которая не требует пользовательского ввода. Проблема может быть воспроизводимой только на одной машине без перезагрузки между воспроизведениями из-за того, как Windows может выбрать размещение памяти.
Воспроизведите проблему и запишите адрес данных экземпляра, память которого повреждена.
Повторно запустите и проверьте второе воспроизведение: убедитесь, что адрес данных экземпляра, поврежденных во втором запуске, совпадает с адресом первого запуска.
Теперь, перейдя в третий прогон, поместите 4-байтовую точку останова данных в раздел памяти, указанный двумя предыдущими прогонами. Этот пункт заключается в разрыве каждой модификации этой памяти. По крайней мере один разрыв должен быть вызовом Tobject.InitInstance, который заполняет указатель VMT; могут быть другие, связанные с конструкцией экземпляра, такие как в распределителе памяти; и в худшем случае соответствующие данные экземпляра могут быть повторно использованы в памяти из предыдущих экземпляров. Чтобы сократить количество необходимых шагов, запишите в журнал точек останова данные стек вызовов, но не прерывать его. Проверяя стеки вызовов после сбоя виртуального вызова, можно найти неверную запись.
В 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.
Расшифруйте некоторые буквы следующего самого длинного зашифрованного слова.
Если некоторые буквы совпадают, добавьте остальные буквы в KeyArray, это версия 2.
Расшифруйте некоторые буквы следующего самого длинного зашифрованного слова.
Повторяйте до тех пор, пока все слова не будут расшифрованы.
Если в версии 0 ни одно из самых длинных слов не создает частичную расшифровку в более короткие слова, очень вероятно, нет решения.
Незначительная оптимизация может быть выполнена путем перечисления возможностей перед выполнением обратного отслеживания. В 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: Переключение на набор вместо списка и добавление кода печати.
Еще одна возможная оптимизация, если у вас есть «достаточно», чтобы иметь значение «достаточно», чтобы иметь дело, и вы знаете язык текста, вы можете использовать буквенные частоты (см.: http://en.wikipedia.org/wiki/letter_frequency
). Это, конечно, очень приблизительный подход при работе с 6/7 слов, но будет самым быстрым способом, если у вас есть несколько страниц для декодирования.
Отредактируйте: о решении Max, вы можете попытаться извлечь некоторые характеристики слова тоже, такие как повторяющиеся буквы. Очевидно, что замечает, что слойки в словаре и Qymm в зашифрованном тексте являются единственными четырем буквенными словами, заканчивающимися с двойной буквой, дает прямой ответ на 3 из букв. В более сложных сценариях вы должны уметь сузить возможности для каждой парольной пары.