Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii_po_PAYa_2-y_semestr.doc
Скачиваний:
4
Добавлен:
27.10.2018
Размер:
453.12 Кб
Скачать

Различные объединения типов. Записи типов с вариантами.

Синтаксис: список полей есть выражение вида

L=N1:T1,…,Nm:Tm.

где Ni – список идентификаторов

Ti – произвольный тип, кроме файла.

record

L

end;

Общий синтаксис типа record:

record

L0 {Знакомый нам синтаксис – общая часть записи. В любой переменной данного типа присутствуют поля из этого списка}

case S:Ts of

c1:(L1); Поле S типа Ts также присутствует во всех значениях типа.

. . .

cm:(Lm); вариантная часть записи

end; S – селектор

end;

c1,…,cm – значения типа Ts

Предполагается, что в значении данного типа присутствуют лишь поля одного из списков Li в зависимости от значения поля S.

* x.S=ci

x:record

L0, S : Ts : Li

end;

N1 N2 N3

type

tInfo=record

case этоInteger:boolean of

true: (IntInfo:integer);

false: (CharInfo:char);

end;

end;

Условие * не проверяется автоматически.

x.этоInteger:=true;

write(x.CharInfo);

Примечание. Записи с вариантами хороши для объединения нескольких явно заданных типов, но не для описания всех типов, например, всех типов, обладающих каким-либо свойством.

Пример: невозможно параметрическое определение типа: stack of T.

Создание дерева. Перевод из префиксной записи. Представление записи.

Дан текстовый файл exp, содержащий правильно построенное выражение.

Требуется создать дерево:

((x+1)*y)/2

/*+x1y2

Пока в выражении идут имена функций идём налево.

Натыкаемся на старую проблему: нужно вернуться на предыдущую вершину.

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

procedure Create(var exp:text;var root:pNode);

var stack:tStack {Стек ссылок на вершины}

c:char; pt:pNode;

begin {Корень создаём отдельно}

reset(exp);

read(exp,c);

root:=NewNode(c); {Создаём вершину с содержимым атрибутом c}

push(stack,root);

while not eof(exp) do

begin

read(exp,c);

while c in [‘+’ , ’-‘ , ’/’ , ’*’] do

begin

pt^.left:=NewNode(c);{Ссылка на текущую вершину дерева}

pt:=pt^.left;

push(stack,pt);

read(exp,c);

end;

pt^.left:=NewNode(c);

read(exp,c);

pt^.right:=NewNode(c);

pt:=pt^.right;

pop(stack,pt);

end;

end;

Примечание: на практике exp нельзя использовать как логическое имя файла! Здесь это использовалось в силу того, что expression (англ.) – выражение.

Анализ алгоритма вычисления. Дерево как последовательность ветвей.

Дано выражение в текстовом файле. Вычислить значение выражения.

Дерево – естественная форма представления выражений, но неэффективно по расходу памяти. Если алгоритм сводится к последовательной обработке компонент некоторой последовательности в естественном порядке, не нужно держать в памяти всю последовательность. В алгоритме вычисления в каждый момент времени используются сведения лишь об одной ветке дерева (ссылка на которую хранится в стеке).

function NewNode(c:char):pNode;

var NewPt:pNode;

begin

new(NewPt);

NewPt^.info:=c;

NewPt^.left:=nil;

NewPt^.right:=nil;

NewNode:=NewPt;

end;

type

tInfo=record

case этоInteger:boolean of

true (IntInfo:integer);

false (CharInfo:char);

end;

end;

function ExpVal(var exp:text;VarVal: tVarVal):integer; {tVarVal  tVariable)}

var stack:tStack; {tStack of tInfo}

begin

create(stack); {Стек символов}

ReadChar(exp,f);

ReadChar(exp,x);

push(stack,f);

push(stack,x);

while not eof(exp) do

begin

{Пока не нашли атом, читай символы и складывай в стек}

pop(stack,x);

pop(stack,f); {/*+x1y2}

ReadChar(exp,c);

while not Atom(f,x,y) do

begin

push(stack,f);

push(stack,x);

push(stack,y);

pop(stack,x);

pop(stack,f);

ReadChar(exp,c);

end;

push(stack,AtomVal(f,x,y));

end;

pop(stack,x);

ExpVal:=x.IntInfo;

end;

Мы упоминали об относительности взгляда на структуры (деревья, графы) как на структуры данных и структуры управления. То, что раньше мы воспринимали как структуру данных (в первом алгоритме), стало трассой вычисления.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]