- •Введение
- •Лабораторная работа №1. Создание простого приложения
- •1 ) Последовательность действий по созданию интерфейса пользователя
- •2) Последовательность действий по программированию щелчка по командным кнопкам (программирование событий):
- •3) Компиляция и выполнение приложения
- •1) Последовательность действий по созданию интерфейса пользователя
- •2) Последовательность действий по программированию событий
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа №2. Циклические программы. Многострочное поле memo
- •1) Последовательность действий по созданию интерфейса пользователя
- •2) Последовательность действий по программированию щелчка по командным кнопкам (программирование событий)
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа №3. Работа с одномерными массивами
- •1) Последовательность действий по созданию интерфейса пользователя
- •2) Последовательность действий по программированию событий
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа № 4. Работа с двумерными массивами
- •Контрольные вопросы
- •Лабораторная работа № 5. Процедуры и функции в delphi
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа № 6. Рекурсивные процедуры и функции
- •Контрольные вопросы
- •Лабораторная работа №7. Разработка приложения с несколькими модулями
- •2) Последовательность действий по программированию событий
- •Лабораторная работа №8. Работа со строками
- •1) Последовательность действий по созданию интерфейса пользователя
- •2) Последовательность действий по программированию событий
- •3) Откомпилируйте приложение и проверьте его работу задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа №9. Создание текстового редактора
- •Задание для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа № 10. Методы простой сортировки
- •Задание для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа № 11. Поиск данных в массиве
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа №12. Работа с файлами
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа №13. Работа с типизированными файлами (файлы записей)
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа № 14. Динамические структуры данных . Стек и очередь
- •Задания для самостоятельной работы
- •Контрольные вопросы
- •Лабораторная работа № 15. Практическое применение стека и очереди
- •Лабораторная работа №16. Линейные списки
- •Лабораторная работа №17. Работа с бинарными деревьями поиска
- •Задание для самостоятельной работы
- •Лабораторная работа №18. Основы объектно-ориентированного программирования
- •Задание для самостоятельной работы
- •Лабораторная работа №19. Графика в delphi. Компоненты shape и chart
- •Контрольные вопросы
- •Лабораторная работа №20. Графика в delphi. Рисование по пикселам и пером
- •Контрольные вопросы
- •Лабораторная работа № 21. Вычисление суммы ряда
- •Литература
- •Содержание
- •214013 Г. Смоленск, Энергетический проезд, 1
Задания для самостоятельной работы
В созданное приложение добавьте две кнопки:
Переписать стек в очередь
Переписать очередь в стек
Контрольные вопросы
Как расшифровывается аббревиатура FIFO и LIFO? Какая из них соответствует очереди, а какая стеку?
Какая указатели требуются для организации работы очереди и стека?
Что является признаком пустого стека и очереди?
Лабораторная работа № 15. Практическое применение стека и очереди
ЦЕЛЬ РАБОТЫ: Получения навыка практической работы с динамическими структурами данных.
ПОДГОТОВКА К РАБОТЕ:
Изучить правила преобразования арифметических выражений из инфиксной формы записи числа в префиксную и постфиксную формы.
Изучить алгоритмы вычисления арифметических выражений, представленных в префиксной и постфиксной формах.
Рассмотреть случаи использования стека и очереди в системном программировании, операционных системах, при создании компиляторов и т.д.
ЗАДАНИЕ 1: Разработать программу проверки правильности расстановки скобок с помощью стека.
В данной программе сделаны следующие упрощения – считается, что арифметическое выражение составлено только из чисел от 0 до 9. Экранная форма приложения приведена на рисунке 15.1.
П оследовательность действий:
В блоке Type после объявления класса формы создайте структуру данных «элемент стека» и указатель на элемент стека:
ps=^Stack;
Stack=Record
data:Char;
next:ps;
end;
В области глобальных переменных объявите указатель на вершину стека:
var
Form1: TForm1;
head:ps;
implementation
…………………….
Для события OnCreate формы напишите следующий программный код:
procedure TForm1.FormCreate(Sender: TObject);
begin
// При запуске программы стек пуст
head:=nil;
end;
Для события 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;
Откомпилируйте приложение и проверьте его работу.
ЗАДАНИЕ 2:Выполните преобразование выражения из инфиксной формы в постфиксную и выполните вычисление выражения в постфиксной форме. Компоненты приложения приведены в таблице 15.1. Экранная форма приложения приведена на рисунке 15.2.
Таблица 15.1 Компоненты приложения
Компонент |
Класс |
Описание |
Edit1 |
TEdit |
Окно ввода выражения в инфиксной форме |
Edit2 |
TEdit |
Окно вывода преобразованного выражения в постфиксной форме |
Edit2 |
TEdit |
Окно вывода результата вычисления выражения в постфиксной форме |
Button1 |
TButton |
Командная кнопка «Начать преобразование» |
Алгоритм преобразования выражения из инфиксной формы в постфиксную следующий:
Исходная строка просматривается слева направо. Символы помещаются в результирующую строку, а открывающие скобки и знаки операций в стек. Будем считать, что в выражении присутствуют только круглые скобки;
Каждой операции назначается приоритет:
«(» имеет приоритет 0;
«+» и «-» - приоритет 1;
«*» и «/» - приоритет 2;
«^» - приоритет 3;
Если встретилась открывающая круглая скобка, то ее заносим в стек;
Если встретился знак операции (+, -, *, /), то анализируем, что находится в вершине стека:
Если «(», то просто помещаем знак операции в стек;
В противном случае, сравниваем приоритет операций. Если приоритет операции, находящейся в вершине стека больше или равен, чем у той, которую хотим поместить в стек, то извлекаем знак операции из вершины стека и помещаем его в результирующую строку. А затем помещаем в стек знак очередной операции. Если стек пуст, то просто помещаем знак операции в стек;
Если очередной символ «)», то извлекаем из стека очередной символ. В том случае, когда очередной символ «(» - ничего не делаем, в противном случае извлекаем очередной символ из стека и помещаем в результирующую строку. Пункт 5 повторяется до тех пор, пока не встретится «(» или стек не станет пуст.
Все остальные встреченные символа (кроме скобок и знаков операций) – операнды. Их помещаем в результирующую строку.
Когда просмотр исходной строки закончен, из стека извлекаются все символы (кроме открывающих скобок) и помещаются в результирующую строку.
Алгоритм вычисления выражения, записанного в постфиксной форме следующий:
Исходная строка просматривается слева направо. Если очередной символ - операнд, он записывается в стек;
Когда мы достигаем знака операции, то относящиеся к ней операнды, будут двумя верхними элементами стека.
Два верхних элемента извлекаются из стека, над ними осуществляется указанная операция, а результат записывается в стек. Тем самым он станет доступен в качестве операнда применительно к следующей операции.
Когда просмотр всей строки закончен, стек должен быть пуст.
Последовательность действий:
В блоке Type после объявления класса формы создайте две структуры и указатели на них:
Первая структура и указатель имеет вид:
TStack=^Elem;
Elem=record
data:char;
next:tstack;
end;
Они используются для преобразования выражения из инфиксной формы в постфиксную.
Вторая структура и указатель имеет вид:
TNumStack=^TNum;
TNum=record
data:real;
next:TNumStack;
end;
Они используются для вычисления выражения в постфиксной форме.
В области глобальных переменных объявите следующие переменные:
Var
Form1: TForm1;
// Вершина стека при преобразовании выражения
//из инфиксной формы в постфиксную
stack: TStack;
// Вершина стека при вычислении выражения в постфиксной форме
res: TNumStack;
// Исходная строка (в инфиксной форме)
str: string;
s,ts: string;
// Очередной обрабатываемый символ
ch:char;
// Номер очередного элемента строки
i:integer;
В блок 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;
В блок implementation поместите функцию пустой стек или нет:
function empty(p:tstack):boolean;
begin
empty:=p=Nil;
end;
В блок 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;
В блок 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;
В блок implementation поместите функцию записи операнда в стек. Данная функция потребуется при вычислении выражения в постфиксной форме:
procedure Ins(n:real; var p:tnumstack);
var q:Tnumstack;
begin
new(q);
q^.data:=n;
q^.next:=p;
p:=q;
end;
В блок 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;
В блок 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;
В блок 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;
Для события 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;
Откомпилируйте приложение и проверьте его работу.
ЗАДАНИЕ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
Разработать программу преобразования выражения из инфиксного в префиксное представление.
Разработайте программу вычисления выражения в префиксной форме.
КОНТРОЛЬНЫЕ ВОПРОСЫ
Преобразовать выражение в префиксную и постфиксную формы:
((A + B) * C - (D + E)) ^ (F - G)
Перевести выражение из префиксной в инфиксную форму: / / - A B * C ^ A B C
Вычислить выражение, записанное в постфиксной форме при A=5, B=3, C=2.
A B C * + A B – C ^ /
Перевести выражение из постфиксной в инфиксную форму: A B C * + A B – C ^ /