- •По дисциплине «Теория алгоритмов»
- •Глава 1. Машина Тьюринга
- •1. Теоретические сведения
- •1.1 Краткое описание машины Тьюринга
- •Глава 1. Машина Тьюринга 4
- •1. Теоретические сведения 4
- •2. Практическая часть: Примеры на составление программ для мт 9
- •Глава 2. Нормальные алгоритмы Маркова 31
- •1. Теоретические сведения 31
- •2.Практическая часть: Примеры на составление нам 34
- •Глава 3. Задачи теоретического характера 57
- •Глава 4. Машина Поста. 72
- •1.2 Программа для машины Тьюринга
- •1.3 Правила выполнения программы
- •1.4 Соглашения для сокращения записи
- •2. Практическая часть: Примеры на составление программ для мт
- •Практическая работа №1: Перемещение автомата, замена символов, анализ символов.
- •Задачи для решения
- •Практическая работа №2 Сравнение символов, стирание слова, удаление символа из слова.
- •Задачи для решения
- •Практическая работа №3: Сжатие слова, вставка символа в слово.
- •Задачи для решения
- •Практическая работа № 4: Раздвижка слова, формирование слова на новом месте, фиксирование места на ленте.
- •Задачи для решения
- •Глава 2. Нормальные алгоритмы Маркова
- •1. Теоретические сведения
- •1.1 Краткое описание нормальных алгоритмов Маркова
- •4. Если в левой части формулы подстановки указано пустое слово, то подстановка сводится, по определению, к приписыванию в слева к слову p:
- •1.2 Правила выполнения нам
- •2.Практическая часть: Примеры на составление нам
- •Практическая работа №5: Вставка и удаление символов, перестановка символов
- •Практическая работа №6: Использование спецзнака, фиксация спецзнаком заменяемого символа.
- •Практическая работа № 7: Перемещение спецзнака, смена спецзнака.
- •Практическая работа № 8: Перенос символа через слово, использование нескольких спецзнаков.
- •Глава 3. Задачи теоретического характера
- •Задачи для решения.
- •Практическая работа №10 Самоприменимость алгоритма
- •Задачи для решения.
- •Глава 4. Машина Поста.
- •Практическая работа №13. Работа с массивами
- •Практическая работа №14 Ориентация на ленте
- •Практическая работа 15. Действия над заданным на ленте множеством меток
- •Практическая работа 16. Сравнение
- •Простые программы
- •Литература
Практическая работа № 8: Перенос символа через слово, использование нескольких спецзнаков.
Пример 1. (перенос символа через слово) А={a,b}. Перенести в конец непустого слова Р его первый символ. Пустое слово не менять.
Например:
Решение.
Для решения этой задачи предлагается выполнить следующие действия.
Помечаем первый символ слова P спецзнаком *.
Заменяем * и этот символ на новый символ: a на A, b на B. Этим мы фактически вводим два новых спецзнака A и B, которые нужны, чтобы отличить первый символ слова от остальных символов при его переносе в конец слова.
Перегоняем новый символ A или B через все символы слова P в его конец. Такое перемещение реализуется аналогично перегону звёздочки - с помощью формул вида
Наконец, заменяем A или B в конце слова на прежний символ (A на a, B на b) и останавливаем алгоритм.
Все эти действия реализуются в виде следующего НАМ:
Проверим этот алгоритм на входном слове bаbа и на входном слове из одного символа:
Другое решение
Отметим, что в этом НАМ можно уменьшить число формул, если не вводить новые символы A и B, а использовать вместо них пары *а и *b. Это позволит исключить из НАМ формулы (1) и (2), которые вводят символы A и B, и формулы (7) и (8), которые восстанавливают первый символ. Что же касается «перепрыгивания» этих пар через какой-то символ то оно реализуется формулами вида *а£а£*а и *b£a£*b. При этом никакой путаницы между первым символом слова и остальными символами не будет, т.к. только перед первым символом находится звёздочка.
Проверим
этот алгоритм на прежнем входном слове
bbaba:
Пример 2 (использование нескольких спецзнаков) А={а,b}. Удвоить слово Р, т.е. приписать к P (слева или справа) его копию.
Например:
Решение.
Предлагается следующий план решения задачи:
Приписываем к концу слова Р символ =, справа от которого будем строить копию P.
Просматриваем по очереди все символы слова Р и, не уничтожая их, переносим копию каждого символа в конец.
3. Удаляем символ =, который отделял слово P от его копии, и останавливаем алгоритм.
Теперь уточним этот план.
Как приписать некоторый символ к концу слова, мы уже знаем: надо сначала приписать слева к слову какой-то спецзнак, скажем *, затем перегнать его направо через все символы слова и в конце, когда за * не окажется никакого символа, заменить на символ =:
Из предыдущего примера мы также знаем, как переносить символы слова в конец слова. Только теперь сами символы уничтожать уже не надо. Поэтому поступаем так: если надо скопировать символ a, то порождаем за ним новый символ A (заменяем a на aA), после чего этот символ A переставляем с каждым последующим символом (в том числе и с символом =), перенося тем самым A в конец слова, где и заменяем на a:
Аналогично копируются и символы b.
Главный вопрос здесь: как узнать, какой именно символ исходного слова мы только что скопировали и какой символ надо копировать следующим? Для этого используем стандартный приём со спецзнаком - будем помечать новым спецзнаком # тот символ, который должен копироваться следующим (вначале это первый символ входного слова):
Как только копия очередного символа окажется в конце, спецзнак # должен «запустить» процесс копирования следующего символа:
Когда справа от спецзнака # окажется символ =, это будет означать, что входное слово полностью скопировано. Осталось только уничтожить символы # и =, после чего остановиться.
Теперь
отметим, что в НАМ, реализующем такое
копирование, важен взаимный порядок
расположения формул (
',
A→a
и
B→b),
которые
переносят символы
A
и
B
в
конец и там восстанавливают символы
a
и
b,
и
формулами
(#a^a#A
и
#b→b#B),
которые
«вводят в игру» символы
A
и
B.
Поскольку
последняя пара формул должна срабатывать
только после того, как символ
A
или
B
будет
полностью перенесён в конец и заменён
на
a
или
b,
то
эта пара формулы должна располагаться
в НАМ ниже всех первых формул.
И ещё один момент. В этом НАМ используются два спецзнака * и #, первый из которых нужен для приписывания символа = справа к входному слову, а второй - для указания, какой символ слова должен копироваться следующим. Как ввести эти спецзнаки? Отметим, что использовать для этого две формулы→* и → #, нельзя, т.к. первая из них будет блокировать доступ ко второй. Оба этих спецзнака надо вводить сразу одной формулой→ #*. При этом надо учитывать, что формулы c* должны применяться самыми первыми, поэтому они должны располагаться в начале НАМ. Формулы же c #, A и B должны располагаться ниже, чтобы они работали только после того, как исчезнет * и появится символ =.
С учётом всего сказанного получаем следующий НАМ:
Здесь формулы (1)-(3) «перегоняют» звёздочку в конец входного слова и заменяют её на символ =. Формулы (4)-(7) перегоняют символ A в конец слова, после чего заменяют на a. Формулы (8)—(11) делают то же самое с B и b. Формулы (12 и (13) «вводят в игру» символы A и B, соответствующие тому символу входного слова, который должен быть скопирован следующим. Формула (14) применяется только тогда, когда справа от # нет ни a, ни b, т.е. когда полностью просмотрено всё входное слово. И, наконец, формула (15) вводит сразу два спецзнака # и *.
Проверим данный алгоритм на двух входных словах - на пустом и на abb:
(т.е.
получили <пустое слово><пустое
слово>)
Другое решение
Приведём ещё одно решение задачи удвоения слова, в котором предлагается выполнить следующие действия.
1. Сначала за каждой (малой) буквой входного слова вставляем её двойник - соответствующую большую букву. Для этого приписываем слева к слову спецзнак *, а затем переносим его через каждую малую букву так, чтобы слева от него остались эта буква и её двойник. В конце слова заменяем * на новый спецзнак #, который нам ещё понадобится:
В получившемся слове переставляем малые и большие буквы так, чтобы слева оказались все малые буквы, а справа - все 2. большие, сохраняя при этом исходный взаимный порядок как среди малых, так и среди больших букв:
3. Как видно, справа мы получили копию входного слова, но записанную большими буквами. Осталось только заменить их на малые буквы. Вот здесь-то и понадобится спецзнак #: будем перемещать его влево через каждую большую букву с заменой её на малую. Когда слева от # уже не окажется большой буквы, надо уничтожить # и остановиться:
Все указанные действия описываются в виде следующего НАМ:
Замечания:
1.В задачах рассматриваются только целые неотрицательные числа, если не сказано иное.
2.Под «единичной» системой счисления понимается запись неотрицательного целого числа с помощью палочек - должно быть выписано столько палочек, какова величина числа; например: 2→ | | , 5 → | | | | | , 0 →<пустое слово>.
Перенести
последний символ непустого слова P в
начало слова.
.
В непустом слове P переставить первый
и последний символы.
.
Если в непустом слове P совпадают первый
и последний символы, то удалить оба
этих символа, а иначе слово не менять.
.
Определить, является ли слово P палиндромом
(перевёртышем, симметричным словом).
Ответ: слово a, если является, или пустое
слово иначе.
.
Пусть слово P имеет нечётную длину.
Удалить из него средний символ.Пусть слово P имеет следующий вид:
где
-
один из знаков
,
слева от которого указано n палочек, а
справа - m палочек. Реализовать соответствующую операцию в единичной системе счисления (в качестве ответа выдать слово, указанное справа от стрелки):
A={ | }. Считая слово P записью числа в единичной системе, определить, является ли это число степенью 3 (1, 3, 9, 27, ...). Ответ: пустое слово, если является, или слово из одной палочки иначе.
A={ | }. Считая слово P записью числа n в единичной системе, получить в этой же системе число 2n.
A={ | }. Пусть слово P является записью числа 2n (n=0, 1, 2, ...) в единичной системе. Получить в этой же системе число n.
Пусть P имеет вид Q+R, где Q и R - непустые слова из символов 0, 1 и 2. Трактуя Q и R как записи троичных чисел (возможно, с незначащими нулями), выдать в качестве ответа запись суммы этих чисел в той же троичной системе.
Пусть P имеет вид Q-R, где Q и R - непустые слова из символов 0, 1 и 2. Трактуя Q и R как записи неотрицательных троичных чисел (возможно, с незначащими нулями) и считая, что Q>R, выдать в качестве ответа запись разности этих чисел в той же троичной системе.
Пусть P имеет вид Q=R, где Q и R - любые слова из символов α и b. Выдать ответ а, если слова Q и R одинаковы, и пустое слово иначе.
Пусть P имеет вид Q=R, где Q и R - непустые слова из символов 0 и 1. Трактуя Q и R как записи двоичных чисел (возможно, с незначащими нулями), выдать в качестве ответа слово 1, если эти числа равны, и слово 0 иначе.
Пусть P имеет вид Q>R, где Q и R - непустые слова из символов 0 и 1. Трактуя Q и R как записи двоичных чисел (возможно, с незначащими нулями), выдать в качестве ответа слово 1, если число Q больше числа R, и слово 1 иначе.
A={( , )}. Определить, сбалансировано ли слово P по круглым скобкам. Ответ: Д (да) или Н (нет)
A={a,b}. Перевернуть слово P (например: abb →bba).
