Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЯВУ.doc
Скачиваний:
6
Добавлен:
12.11.2019
Размер:
1.51 Mб
Скачать

Задания для самостоятельной работы

В созданное приложение добавьте две кнопки:

  1. Переписать стек в очередь

  2. Переписать очередь в стек

Контрольные вопросы

  1. Как расшифровывается аббревиатура FIFO и LIFO? Какая из них соответствует очереди, а какая стеку?

  2. Какая указатели требуются для организации работы очереди и стека?

  3. Что является признаком пустого стека и очереди?

Лабораторная работа № 15. Практическое применение стека и очереди

ЦЕЛЬ РАБОТЫ: Получения навыка практической работы с динамическими структурами данных.

ПОДГОТОВКА К РАБОТЕ:

  1. Изучить правила преобразования арифметических выражений из инфиксной формы записи числа в префиксную и постфиксную формы.

  2. Изучить алгоритмы вычисления арифметических выражений, представленных в префиксной и постфиксной формах.

  3. Рассмотреть случаи использования стека и очереди в системном программировании, операционных системах, при создании компиляторов и т.д.

ЗАДАНИЕ 1: Разработать программу проверки правильности расстановки скобок с помощью стека.

В данной программе сделаны следующие упрощения – считается, что арифметическое выражение составлено только из чисел от 0 до 9. Экранная форма приложения приведена на рисунке 15.1.

П оследовательность действий:

  1. В блоке Type после объявления класса формы создайте структуру данных «элемент стека» и указатель на элемент стека:

ps=^Stack;

Stack=Record

data:Char;

next:ps;

end;

  1. В области глобальных переменных объявите указатель на вершину стека:

var

Form1: TForm1;

head:ps;

implementation

…………………….

  1. Для события OnCreate формы напишите следующий программный код:

procedure TForm1.FormCreate(Sender: TObject);

begin

// При запуске программы стек пуст

head:=nil;

end;

  1. Для события OnClick кнопки Button1 («Пуск») напишите следующий программный код:

procedure TForm1.Button1Click(Sender: TObject);

var s:string;

i:integer;

p:ps;

f:Boolean;

begin

// s- строка, содержащая проверяемое выражение

s:=edit1.Text;

f:=True;

For i:=1 to Length(s) do

Begin

// Если очередной символ строки открывающая скобка, она помещается в стек

If (s[i]='(') or (s[i]='[') or (s[i]='{') then

begin

new(p);

p^.data:=s[i];

p^.next:=head;

head:=p;

end ;

// Если очередной символ строки закрывающая скобка и стек не пуст

// извлекается элемент, находящийся на вершине стека

// и сравнивается тип скобок

If (s[i]=')') or (s[i]=']') or (s[i]='}') then

begin

If head=nil then f:=False

else

begin

p:=head;

head:=p^.next;

case s[i] of

')': If p^.data<>'(' then f:=False;

']': If p^.data<>'[' then f:=False;

'}': If p^.data<>'{' then f:=False;

end;

dispose(p);

// если скобки не совпадают – досрочное завершение

// цикла проверки

If f=False then break;

end;

end;

end;

If (head<>nil) or (f=False) then Showmessage('Ошибка')

else Showmessage('Скобки расставлены правильно');

end;

  1. Откомпилируйте приложение и проверьте его работу.

ЗАДАНИЕ 2:Выполните преобразование выражения из инфиксной формы в постфиксную и выполните вычисление выражения в постфиксной форме. Компоненты приложения приведены в таблице 15.1. Экранная форма приложения приведена на рисунке 15.2.

Таблица 15.1 Компоненты приложения

Компонент

Класс

Описание

Edit1

TEdit

Окно ввода выражения в инфиксной форме

Edit2

TEdit

Окно вывода преобразованного выражения в постфиксной форме

Edit2

TEdit

Окно вывода результата вычисления выражения в постфиксной форме

Button1

TButton

Командная кнопка «Начать преобразование»

Алгоритм преобразования выражения из инфиксной формы в постфиксную следующий:

  1. Исходная строка просматривается слева направо. Символы помещаются в результирующую строку, а открывающие скобки и знаки операций в стек. Будем считать, что в выражении присутствуют только круглые скобки;

  1. Каждой операции назначается приоритет:

  • «(» имеет приоритет 0;

  • «+» и «-» - приоритет 1;

  • «*» и «/» - приоритет 2;

  • «^» - приоритет 3;

  1. Если встретилась открывающая круглая скобка, то ее заносим в стек;

  2. Если встретился знак операции (+, -, *, /), то анализируем, что находится в вершине стека:

    1. Если «(», то просто помещаем знак операции в стек;

    2. В противном случае, сравниваем приоритет операций. Если приоритет операции, находящейся в вершине стека больше или равен, чем у той, которую хотим поместить в стек, то извлекаем знак операции из вершины стека и помещаем его в результирующую строку. А затем помещаем в стек знак очередной операции. Если стек пуст, то просто помещаем знак операции в стек;

  1. Если очередной символ «)», то извлекаем из стека очередной символ. В том случае, когда очередной символ «(» - ничего не делаем, в противном случае извлекаем очередной символ из стека и помещаем в результирующую строку. Пункт 5 повторяется до тех пор, пока не встретится «(» или стек не станет пуст.

  2. Все остальные встреченные символа (кроме скобок и знаков операций) – операнды. Их помещаем в результирующую строку.

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

Алгоритм вычисления выражения, записанного в постфиксной форме следующий:

  1. Исходная строка просматривается слева направо. Если очередной символ - операнд, он записывается в стек;

  2. Когда мы достигаем знака операции, то относящиеся к ней операнды, будут двумя верхними элементами стека.

  3. Два верхних элемента извлекаются из стека, над ними осуществляется указанная операция, а результат записывается в стек. Тем самым он станет доступен в качестве операнда применительно к следующей операции.

  4. Когда просмотр всей строки закончен, стек должен быть пуст.

Последовательность действий:

  1. В блоке Type после объявления класса формы создайте две структуры и указатели на них:

    1. Первая структура и указатель имеет вид:

TStack=^Elem;

Elem=record

data:char;

next:tstack;

end;

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

    1. Вторая структура и указатель имеет вид:

TNumStack=^TNum;

TNum=record

data:real;

next:TNumStack;

end;

Они используются для вычисления выражения в постфиксной форме.

  1. В области глобальных переменных объявите следующие переменные:

Var

Form1: TForm1;

// Вершина стека при преобразовании выражения

//из инфиксной формы в постфиксную

stack: TStack;

// Вершина стека при вычислении выражения в постфиксной форме

res: TNumStack;

// Исходная строка (в инфиксной форме)

str: string;

s,ts: string;

// Очередной обрабатываемый символ

ch:char;

// Номер очередного элемента строки

i:integer;

  1. В блок implementation поместите функцию извлечения элемента из стека:

function pop(var p:tstack):char;

var q:tstack;

begin

if p<>Nil then

begin

pop:=p^.data;

q:=p;

p:=p^.next;

dispose(q);

end

else pop:=' ';

end;

  1. В блок implementation поместите функцию пустой стек или нет:

function empty(p:tstack):boolean;

begin

empty:=p=Nil;

end;

  1. В блок implementation поместите функцию сравнения приоритетов двух операций;

function lowerprior(a,b:char):boolean;

var i,j:integer;

function prior(c:char):integer;

begin

case c of

'(' :prior:=0;

'+','-':prior:=1;

'/','*':prior:=2;

'^' :prior:=3;

end;

end;

begin

lowerprior:=prior(a)-prior(b)<0;

end;

  1. В блок implementation поместите функцию записи знака операции в стек и сравнения приоритетов операций на вершине стека и операции, помещаемой в стек:

procedure push(elm:char; var p:tstack);

var q:tstack;

begin

str:=str+' ';

if elm<>'(' then

while (p<>nil) and (not lowerPrior(p^.data, elm)) do

str:=str+pop(p);

new(q);

q^.data:=elm;

q^.next:=p;

p:=q;

end;

  1. В блок implementation поместите функцию записи операнда в стек. Данная функция потребуется при вычислении выражения в постфиксной форме:

procedure Ins(n:real; var p:tnumstack);

var q:Tnumstack;

begin

new(q);

q^.data:=n;

q^.next:=p;

p:=q;

end;

  1. В блок implementation поместите функцию вычисления степени числа и записи результата операции в стек. Данная функция потребуется при вычислении выражения в постфиксной форме:

function pow(x,y:real):real;

var i:integer;

ans:real;

begin

ans:=1;

for i:=1 to round(abs(y)) do ans:=ans*x;

if y<0 then pow:=1/ans

else pow:=ans;

end;

  1. В блок implementation поместите функцию вычисления для операций +, -, *, / и записи результата операции в стек. Данная функция потребуется при вычислении выражения в постфиксной форме:

procedure count(ch:char; var p:tnumstack);

var q:Tnumstack;

begin

q:=p;

p:=p^.next;

case ch of

'^': p^.data:=Pow(p^.data, q^.data);

'*': p^.data:=p^.data*q^.data;

'/': p^.data:=p^.data/q^.data;

'-': p^.data:=p^.data-q^.data;

'+': p^.data:=p^.data+q^.data;

end;

dispose(q);

end;

  1. В блок implementation поместите функцию преобразования строки в число. Данная функция потребуется при вычислении выражения в постфиксной форме:

function strtofloat(s:string):real;

var n:real;

code:integer;

begin

val(s,n,code);

if code=0 then strtofloat:=n

else strtofloat:=0;

end;

  1. Для события OnClick кнопки Button1 напишите следующий программный код:

procedure TForm1.Button1Click(Sender: TObject);

begin

stack:=nil;

s:=edit1.Text;;

str:=' ';

// Преобразование выражения из инфиксной формы в постфиксную

for i:=1 to length(s) do

case s[i] of

'(', '^', '/', '*', '-', '+': push(s[i],stack);

')': repeat

ch:=pop(stack);

if ch<>'(' then str:=str+' '+ch;

until (ch='(') or empty(stack);

else str:=str+s[i];

end;

while not empty(stack) do

str:=str+pop(stack);

edit2.Text:=str;

res:=nil;

i:=1;

// Вычисление выражения в постфиксной форме

while i<=length(str) do

begin

ts:=' ';

case str[i] of

'0'..'9':begin

while str[i] in ['0'..'9'] do

begin

ts:=ts+str[i];

inc(i);

end;

dec(i);

ins(strtofloat(ts),res);

end;

'^', '/', '*', '-', '+':count(str[i],res);

end;

inc(i);

end;

edit3.Text:=FloatToStr(res^.data);

end;

  1. Откомпилируйте приложение и проверьте его работу.

ЗАДАНИЕ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ

  1. Разработать программу преобразования выражения из инфик­сного в префиксное представление.

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

КОНТРОЛЬНЫЕ ВОПРОСЫ

  1. Преобразовать выражение в префиксную и постфиксную формы:

((A + B) * C - (D + E)) ^ (F - G)

  1. Перевести выражение из префиксной в инфиксную форму: / / - A B * C ^ A B C

  2. Вычислить выражение, записанное в постфиксной форме при A=5, B=3, C=2.

A B C * + A B – C ^ /

  1. Перевести выражение из постфиксной в инфиксную форму: A B C * + A B – C ^ /