Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
oaip_2 / Курсовая ОАиП.doc
Скачиваний:
95
Добавлен:
27.05.2013
Размер:
204.8 Кб
Скачать

Задачи удаления лишних знаков препинания и определения длины каждого слова не являются сложными и их можно реализовать не разбивая их на подзадачи.

Рассмотрим задачу удаления лишних препинаний. Эта задача реализована макросом

DeleteSign. Решить задачу можно определением знаков препинаний и затем“удаления”

их путём затирания буквами, следующих за этими знаками. При этом надо не забывать

уменьшать длину строки в первом байте строки. Также нужно в конец каждого слова

записывать символ запятой, т.к. это записано в задании. Реализовать затирание

знаков препинания можно пересылая байты с буквами на место байтов с препинаниями.

Такую пересылку можно осуществить применив команду MOVSB столько раз сколько это необходимо. Т.о. команда DeleteSign работает по следующему алгоритму:

  1. Найти начало первого слова.

  2. Затереть препинания следующие перед первым словом.

  3. Найти следущее слово.

  4. Затереть препинания следущие перед этим словом.

  5. Повторять п.4 пока не конец предложения.

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

Далее проходя последовательно по строке и находя конец слова вставлять его длину пока предложение не закончится.

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

Одним из возможных вариантов преобразования является табличное преобразование , т.е. по значению регистра R0 мы выбираем из заранее созданной таблицы необходимый символьный эквивалент , например с помощью команды XLAT. Однако такой вариант требует создания таблицы. Но есть у этого варианта и свои преимущества – так например если для записи использовать числа 16-ой или другой системы счисления , где используются не только символы цифр , то этот вариант более предпочтителен.

В данной команде(реализуется в макросе WriteLenWords) будем использовать числа в 10-й системе , как более наглядные. Преобразование производится следущим образом:

Если к примеру в R0 значение длины от 0 до 9 , то преобразовать к символьному эквиваленту достаточно легко прибавив к значению R0 число 4810 или 3016 . Тогда мы получим ASCII код числа. Если же в R0 число 2-ух или выше разрядов , то таким образом мы сможем преобразовать только единицы этого числа , но не десятки , сотни и т.д. Следовательно необходимо “выделить” из этого числа единицы , десятки , сотни и т.д. (в нашем случае только десятки и сотни , т.к. вся строка состоит из 250 символов идля представления самого длинного слова понадобится только 3 знака).

А т.к. числа в 10-й системе представляются так:

Xn*10^N+…+X2*10^2+X1*10^1+X0*10^0=десятичное число

где Хn – значение числа в N – ом разряде

N – разряд

то выделить их можно путем деления на 1 , 10 и 100 тогда каждый раз в остатке получим единичные разряды Xn. Далее прибавляя к ним константу 3016 получим необходимый символ.

Теперь рассмотрим разработку основного и самого сложного алгоритма – сортировка.

Сортировку будем осуществлять методом “пузырька”. Сама сортировка реализована в макросе Sorting. Однако сам макрос использует несколько других более простых макросов , т.е. задачу сортировки мы разбили на более простые подзадачи.

Алгоритм сортировки можно представить следущим образом:

While Flag do

Begin

Flag:= false;

For i:=1 to (N-1) do

if Word[i] > Word[i+1] then

Begin

ChangeWords Word[i] , Word[i+1];

Flag:= true

End;

End.

Где N – число элементов (слов).

Flag – флаг выхода из цикла(если все “пузырки всплыли”)

Word – элементы строки (слова).

Сложность представляет не сам процесс сортировки , и даже не процесс обращения к элементам сортировки – словам , а процесс обмена слов , т.к. слова могут быть различной длины , а команда ChangeWords выполняет обмен слов с одинаковой длиной. Одним из выходов является усложнение алгоритма обмена слов. На первый взгляд это решит проблему , однако решив эту проблему таким образом мы породим еще несколько проблем. В частности придется ввести еще команды которые будут: удалять в строке лишние буквы оставшиеся от более длиного слова и расширять строку для записи более длинного слова. Таким образом придется усложнить алгоритм работы всей программы и , соответственно , увеличить ее размеры и уменьшить быстродействие. Вместо всего этого можно предпринять следущее – в строке все слова “привести к одному размеру“ путем добавления к концу слов пробелов или других знаков препинания. Длина такого слова с добавленними пробелами должна быть равна длине максимального слова в строке. Соответственно к самому длинному слову ничего добавлять не надо. Этим самым мы добились:

  • Не надо писать новых команд расширения и удаления лишних символов

  • Не придется усложнять алгоритм обмена слов

  • Процесс обращения к элементам сортировки (словам) значительно облегчится , т.к. длина всех слов одинакова и тогда они отстоят друг от друга на некоторое постоянное число.

Приведение всех слов к одному размеру осуществляется макросом ToOneSize.

Алгоритм команды заключается в вычислении длины слова , определении его конца и сдвига вправо строки на определенное число равное (длина max слова-длина текущего слова) , этим мы приравниваем все слова к одному размеру. Перед выполнением этой команды мы удаляем из строки все знаки препинания и разделяем слова запятыми. Поэтому при сдвиге кажды предыдущий символ дублируется как символ запятой и нет опасности “появления нового ненужного слова”.

Сдвиг осуществляется макросом ShiftRight offset. Для которого указывается адрес начала сдвига. Далее вычисляется количество сдвигаемых байтов и , с помощью команды MOVSB , производится сдвиг на один байт вправо.

Для нахождения длины максимального слова разработан макрос FindMaxLen. Алгоритм его работы прост – он просматривает строку считая длину текущего слова и сравнивая её с длиной максимального слова , если длина текущего слова больше длины максимального , то длина текущего становится максимальной длиной. Далее максимальная длина записывается в регистр R0 и к нему прибавляется число 5. 5 – это число 3-х цифр и 2-х скобок для записи в конец каждого слова его длины.

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

При разработке будем использовать паскалевский эквивалент приведенный выше.

Для начала сортировки необходимо иметь указатели на сравниваемые слова и флаг устанавливающийся в 1 если мы за один проход совершили хотя бы один обмен , в противном случае все “пузырки всплыли” и сортировка закончена. В качестве указателей будут выступать переменные Р1 и Р2 (можно было бы использовать стандартные регистры , но для улучшения читабельности вводим 2-е переменные). В качестве флага вводим переменную Flag и устанавливаем ее в 1 чтобы не выйти из цикла до его просмотра. Устанавливаем переменную P1 на первое слово , а Р2 на второе (Р1+R0 т.к. в R0 длина максимального слова). Далее сравниваем слова и осуществляем либо обмен либо ищем дальше. Для продолжения сравнения необходимо сдвинуть указатели Р1 и Р2 на следущую пару слов , для этого присваиваем указателю Р1 значение Р2 , а к значению Р2 прибавляем R0. Важным является определение конца строки , т.к. Р2 приходит к концу строки раньше то проверяем не стоит ли Р2 на конце строки. Для этого удобно ввести макрос проверки конца строки TestEnd offset. Он осуществляет сравнение текущего элемента с признаком конца строки “$”. Если Р2 стоит на конце строки , то проверяем произвели ли за этот проход хотя бы один обмен , если да , то продолжаем “выталкивать очередной пузырёк” иначе сортировка закончена.

Рассмотрим еще несколько макросов необходимых для работы программы:

Соседние файлы в папке oaip_2