Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 [ 65 ] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

предыдущее состояние) только строкой а;; и новое значение в строке х - это значение, которое исчезло в результате предыдущего изменения. Короче говоря, имеем следующий алгоритм.

Алгоритм В {Перемножение перестановок, представленных в виде циклов). Этот алгоритм (рис. 21) дает, в сущности, тот же результат, что и алгоритм А. Предположим, что переставляемыми элементами являются Х\,Х2, ,Хп- Будем использовать вспомогательную таблицу Г[1],Т[2],...,Г[п]; по окончании работы алгоритма Xi переходит в Xj в перестановке ввода тогда и только тогда, когда T[i] = j.

Bl. [Инициализация.] Присвоить 1[к] к, где \ <к <п. Подготовиться также к просмотру справа налево.

82. [Следующий элемент.] Рассмотреть следующий элемент ввода (справа налево). Если ввод исчерпан, то работа алгоритма заканчивгьется. Если рассматривгьется элемент ")", то присвоить Z О и повторить шаг В2; если это элемент "(", то перейти к шагу В4. В противном случгье рассматривается элемент Xi для некоторого i; тогда перейти к шагу ВЗ.

83. [Замена T[i].] Выполнить взаимный обмен Z Т\г\. Если в результате получится T[i] = О, то присвоить j i. Вернуться к шагу В2.

84. [Замена Г[;].] Присвоить T[j] Z. (Здесь j-это строка, определяющая элемент ")" в обозначениях табл. 2, т. е. правую скобку, которая соответствует только что просмотренной левой скобке.) Вернуться к шагу В2.

Инициализация

.1 /")"

ХЗледующий элемент/йТ»

Готово

Замена T[i]

Замена T[j]

Рис. 21. Алгоритм В: перемножение перестановок.

Разумеется, после выполнения этого алгоритма необходимо еще вывести содержимое таблицы Т в циклическом виде; как будет показано ниже, это легко сделать методом "пометок".

Теперь на основе нового алгоритма давайте напишем программу для MIX. Будем придерживаться тех же основных правил, что и в программе А, используя такой же формат ввода и вывода, как и раньше. Но тут возникает небольшая проблема: как можно реализовать алгоритм В, не зная наперед, чему равны элементы xi,X2,... ,х„? Неизвестно, чему равно п, а также будет ли элемент Ь равен Xi или Х2 и т. д. Существует простой способ решения данной проблемы - создать таблицу, внести в нее имена элементов, которые уже встречались, и каждый раз искать имя текущего элемента (см. строки 35-44 в программе ниже).



Программа В (Дает тот же результат, что и программа А). гХ = Z; г14 = г; гП = j; rI3 = п, количество различных просмотренных имен.

01 MAXWDS EQU

02 X ORIG

03 Т ORIG

04 PERM ORIG

05 ANS EQU

06 OUTBUF ORIG

07 CARDS EQU

1200

♦+MAXWDS ♦+MAXWDS ♦+MAXWDS PERM *+24 16


МаксимЕшьная длина ввода. Таблица имен.

Вспомогательная таблица состояния. Входная перестановка. Место для ответа. Место для печати.

Совпадают со строками 05-22 программы А. В этот момент г12 слов

ввода находятся в PERM, PERM + 1, ... и мы пока еще не видели ни одного имени. Присвоить Z 0.

82. Следующий элемент.

Пропустить пробелы. Следующим элементом является ")"? Это "("?

Приготовиться к поиску. Сохранить в начале таблицы. Искать в таблице имен.

Повторять до нахождения соответствия. Это имя появлялось ранее? Нет; увеличить размер таблицы. Вставить новое имя Хп-Присвоить Т[п] «- п, i <г- п.

83. Замена Г[г]. Сохранить Z. Установить Z.

Если Z было нулем, присвоить j +- г.

84. Зг.менг.Т\1].

Вернуться к В2, если работа еще не закончена.

Весь ввод просмотрен. Таблицы х кТ содержат ответ. Теперь построим циклическую запись. Имя было помечено? Это единичный цикл?

Открыть цикл.

Пометить имя.



LDAN

MOVE

RPREN

SKIP

DECS

DONE

CMPl

=ANS=

EQUALS ALF

BEGIN

Г Найти элемент, в который переходит этот элемент. Т

Т Он уже помечен?

W Да, цикл закрывается.

Z Перейти к следующему имени.

Совпадают со строками 48-62 программы А.

Строки 54-68, в которых строится циклическая запись на основании таблицы Т и таблицы имен, представляют собой небольшой алгоритм, который заслуживает внимания. Величины А, В, ..., R, S, Т, W, Z, влияющие на время выполнения программы, конечно, отличаются от одноименных величин, которые использовались при анализе программы А. Анализ этих величин будет интересным упражнением для читателя (см. упр. 10).

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

Обратные перестановки. Обратная перестановка тг" для перестановки тг - это такая перестановка, которая отменяет действие тг; если в тг элемент г переходит в j IT, то в 7г~ элемент j переходит в г. Таким образом, произведение тгтг" равняется тождественной перестановке; то же самое справедливо и для произведения 7г~7г. Обратную перестановку часто обозначают через п", а не тг", но верхний индекс 1 явно лишний (по той же причине, по которой = х).

Каждая перестановка имеет обратную. Например, обратной перестановкой для

а Ь с d е f\ fс d f b е

, , , является , ,

cdfbea) \а b с d е

а\ f а b с d е f\ f) ~ \f d а b е с)

Рассмотрим некоторые простые алгоритмы вычисления обратной перестановки.

Предположим, что в оставшейся части раздела мы будем иметь дело с перестановками чисел {1,2, ...,п}. Если А[1] Х[2]... [п] - такая перестановка, то существует простой метод вычисления перестановки, обратной к ней. Присвоим У[А[А;]] 4- к для I <к <п. Тогда У[1] У[2]... У[п] - искомая обратная перестановка. В этом методе используется 2п ячеек памяти, а именно - п для Х и п для Y.

А теперь ради интереса предположим, что п очень велико, в то время как нужно вычислить обратную перестановку к [l] АГ[2]... АГ[п], не используя слишком много дополнительного пространства памяти. Необходимо вычислить обратную перестановку "на месте", чтобы после окончания работы алгоритма массив [l] Х[2]... Х[п] представлял собой перестановку, обратную к первоначальной. Простое присвоение [ArfA;]] 4- к для 1 <к <пъ этом случае, разумеется, не пройдет, но, рассматривая циклическую структуру, можно получить следующий простой алгоритм.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 [ 65 ] 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225