
- •Теоретический раздел лекции Тема 1. Программирование с использованием рекурсии
- •1.1. Cтратегии решения задачи разбиением ее на подзадачи
- •1.2. Программирование рекуррентных соотношений
- •Var z:extended;
- •1.3. Условия окончания рекурсии
- •1.4. О целесообразности использования рекурсии
- •Var I,X,y,z:word;
- •1.5 Правила выбора программной реализации рекуррентных соотношений
- •Тема 2. Задачи перебора вариантов
- •2.1. Модель дерева решений
- •2.2. Задача оптимального выбора (задача о рюкзаке)
- •2.3. Метод полного перебора двоичного дерева
- •Var wt,ct:extended;
- •Var j,k:byte;
- •If k in s then begin
- •Var j:byte;
- •Var j:byte;
- •Var wt1,oct1:byte;
- •2.4. Метод ветвей и границ
- •Var n,I:byte;
- •Var wt1,oct1:Extended;
- •Include(s,I);
- •If I in Sopt then writeln(I,a[I].W,a[I].C);
- •2.5. Эвристические методы
- •Тема 3. Поиск и сортировка массивов записей
- •3.1. Применимость сортировки и поиска
- •3.2. Массив записей и поиск в нем
- •Var m:word;
- •3.3. Сортировки массивов
- •Var c: mas; I,j,k:word;
- •Var m:word;
- •Var I,j:Word;
- •Var I,j,l,r:Word; X:Tk; w:Tzp;
- •Тема 4. Связанные списки с использованием рекурсивных данных
- •4.1. Список, стек, очередь
- •4.2. Списки на основе динамических массивов
- •Inherited create;
- •Var turn:Tlist; с1,c2:Tinf;
- •4.3. Рекурсивные данные и однонаправленные списки
- •Inherited create;
- •Var stec,st1,turn,tr1:Tlist; inf:Tinf;
- •4.4. Начальное формирование, добавление и удаление элементов однонаправленного списка
- •4.5. Разновидности связанных списков
- •Inf:Tinf;
- •Тема 5. Поиск и сортировки на связанных линейных списках
- •5.1. Поиск в однонаправленных списках
- •5.2. Сортировка однонаправленных списков
- •1 3Var Inf:tInf;
- •Тема 6. Использование линейных связанных списков
- •6.1. Вычисления арифметических выражений
- •Var ch,ch1,ch2,chr:char;
- •I:byte;ch,ch1:char;
- •6.2. Сложение больших целых чисел
- •Var u,V,s,t:byte;
- •6.3. Работа с разреженными матрицами
- •Inf:Tinf;
- •Inf:tInf;
- •Var proot,p:Ptree;
- •Var bl:boolean;
- •7.2. Бинарное дерево поиска
- •7.3. Основные операции с бинарным деревом поиска
- •Inf:tInf;
- •Var d1:Tree; c:Tinf; k:Tkey;
- •Var bl:Boolean;
- •Var m:Word;
- •Var p:Ttree; m:Word;
- •Тема 8. Хеширование
- •8.1. Что такое хеширование
- •8.2. Схема хеширования
- •Interface
- •Inf:Tinf;
- •8.4. Другие способы хеширования
- •Практический раздел Указания по выбору варианта
- •Индивидуальные практические работы и контрольные работы
- •Индивидуальная практическая работа №1. Программирование с использованием рекурсии
- •1.1. Понятие рекурсии
- •1.2. Порядок выполнения работы
- •1.2.1. Пример решения задачи
- •Индивидуальная практическая работа №2. Организация однонаправленного списка на основе рекурсивных типов данных в виде стека
- •2.1. Основные понятия и определения
- •Inf:tInf; // информация
- •Контрольная работа №1. Программирование с использованием деревьев на основе рекурсивных типов данных
- •1.1. Понятие древовидной структуры
- •Inf:tInf;
- •1.2. Компонент tTreeView
- •1.3. Бинарное дерево поиска
- •Основные операции с двоичным деревом поиска
- •1.4. Порядок написания программы
- •Inf:tInf;
- •Inherited Free;
- •Var tr:Ttree;
- •1.5. Индивидуальные задания
- •Курсовая работа
- •Литература
Тема 6. Использование линейных связанных списков
6.1. Вычисления арифметических выражений
Одной из задач при разработке трансляторов является задача расшифровки арифметических выражений, например, вида:
r:=(a+b)*(c+d)-e;
Запись выражения вида a+b называется инфиксной формой, причем , a и b операнды, + операция. Возможны также другие формы записи этого выражения: +ab префиксная, ab+ постфиксная. В наиболее распространенной инфиксной форме для указания последовательности выполнения операций необходимо расставлять скобки. Польский математик Я. Лукашевич обратил внимание на тот факт, что при записи выражений в постфиксной форме скобки не нужны, а последовательность операндов и операций удобна для расшифровки основанной на применении эффективных методов. Поэтому постфиксная запись выражений получила название обратной польской записи (ОПЗ). Например, вышеприведенное выражение в ОПЗ выглядит следующим образом:
r=ab+cd+*e–;
Решение задач преобразования инфиксного выражения в постфиксную запись и вычисление выражения в ОПЗ оформим виде класса с соответствующими методами. Используем ранее описанный класс Tlist работы с однонаправленным списком, в котором поле Inf имеет тип Char.
Type Tpz=class
mszn:array[’a’..’я’]of extended;//[a..z..я]
stec:Tlist;
Procedure OBP(Var stri,strp:string);//преобразование
Function AV(strp:string):extended; //вычисление
End;
Алгоритм вычисления выражения в ОПЗ основан на использовании стека. При просмотре выражения слева направо каждый операнд заносится в стек. В результате для каждой операции, относящиеся к ней операнды будут двумя верхними элементами стека. Берем из стека эти операнды, выполняем очередную операцию над этими операндами и результат помещаем в стек. Приведенный ниже метод AV(..) реализует этот алгоритм.
Function Tpz.AV(strp:string):extended;//в strp выражение в ОПЗ
Var ch,ch1,ch2,chr:char;
op1,op2,rez:extended;
begin
stec:=Tlist.create;
chr:=Succ(’z’); //следующий за ’z’ символ
for i:=1 to Length(str)do
begin
ch:=strp[i];
if not ch in [’*’,’/’,’+’,’-’,’^’]
then stec.Add1(ch)
else
begin
stec.Read1(ch2); stec.Read1(ch1);
op1:=mszn[ch1];op2:=mszn[ch2];
case ch of
’+’:rez:=op1+op2;
’-’:rez:=op1-op2;
’*’:rez:=op1*op2;
’/’:rez:=op1/op2;
’^’:rez:=exp(op2*ln(op1));
end;
mszn[chr]:=rez; stec.Add1(chr);Inc(chr);
end; // for
Result:=rez; stec.Free;
end;// AV
Пример вычисления выражения:
Var pz:Tpz;
...
Begin
pz:=Tpz.create;
pz.mszn[’a’]:=0.1; pz.mszn[’b’]:=5.2; pz.mszn[’c’]:=2.4; pz.mszn[’d’]:=6;
pz.mszn[’e’]:=8.4;
write(pz.AV(’ab+cd+*e-’));// вывод результата AV
...pz.free;
end;
Алгоритм преобразования выражения из инфиксной формы в форму обратной польской записи (постфиксную) был предложен Дейкстрой. При его реализации вводится понятие стекового приоритета операций:
Операции )( + – */ ^ (^ - возведение в степень)
Приоритет 0 1 2 3
Просматривается слева направо исходная строка символов, в которой записано выражение в инфиксной форме, причем операнды переписываются в выходную строку в которой формируется постфиксная форма выражения, а знаки операций заносятся в стек следующим образом:
Если стек пуст, то операция записывается в стек;
Открывающаяся скобка дописывается в стек;
Закрывающая скобка выталкивает в выходную строку все операции из стека до ближайшей открывающейся скобки, сами скобки уничтожаются;
Если стек не пуст, то очередная операция выталкивает в выходную строку все операции из стека с большим чем у нее или равным приоритетом до первой менее приоритетной операции, причем сама дописывается в стек;
Если после выборки из исходной строки последнего символа в стеке остались операции, то все они выталкиваются в выходную строку.
// в stri- инфиксное, в strp- постфиксное выражения
Procedure Tpz.OBP(Var stri,strp:string);
Function prior(ch:char):byte;
begin
case ch of
’(’,’)’:prior:=0;
’+’,’-’:prior:=1;
’*’,’/’:proir:=2;
’^’:proir:=3;
end;
end;
Var pc:0..3;