- •Вопрос 1.
- •Вопрос 2.
- •Вопрос 3.
- •Вопрос 4.
- •Вопрос 5.
- •Вопрос 6.
- •Вопрос 7.
- •Вопрос 8.
- •Вопрос 9.
- •Вопрос 10.
- •Вопрос 11.Рекурсия: понятие, пример использования.
- •Вопрос 12. Строки в Delphi. Способы реализации строк. Основные процедуры и функции.
- •Вопрос 13.
- •Вопрос 14.
- •Вопрос 15.
- •Вопрос 16. Программирование с использованием динамической памяти. Структура оперативной памяти. Понятие указателя.
- •Вопрос 17. Указатели. Описание, допустимые операции
- •Вопрос 18. Статические и динамические переменные. Динамические структуры данных
- •19. Линейные списки. Основные операции над линейными списками.
- •21. Стек: понятие, описание в программе, основные операции
- •22. Очередь: понятие, описание в программе, основные операции
- •23. Списки: понятие, описание в программе, основные операции
- •24. Применение динамических структур данных. Проверка математического выражения на правильность расстановки скобок.
- •Вопрос 25.
- •Вопрос 26.
- •Вопрос 27.
- •Вопрос 28.
- •Вопрос 29.
- •Вопрос 30.
- •Вопрос 33.
- •Вопрос 35.
- •Вопрос 36. Операторы инкремента и декремента. Операторы присваивания
- •Вопрос 37. Функции scanf, printf
- •Вопрос 38. Способы задания разветвляющегося алгоритма в с
- •Вопрос 39. Циклические алгоритмы. Виды циклов в с
- •Вопрос 40. Табулирование функции
- •41. Алгоритм вывода всех простых чисел меньших 100 в с.
- •42. Алгоритм разложения числа на простые множители в с
24. Применение динамических структур данных. Проверка математического выражения на правильность расстановки скобок.
procedure CreateSt1;
begin
New(pTop1);
pTop1.next:=nil;
pTop1.d:='1';
end;
procedure Add1(x:String);
var pHelp:pEl;
begin
New(pHelp);
pHelp.next:=pTop1;
pHelp.d:=x;
pTop1:=pHelp;
end;
function Del1:String;
begin
If pTop1.next<>nil then
pTop1:=pTop1.next;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
begin
S:=Edit1.Text;
CreateSt1;
for i:=1 to length(S) do
begin
If S[i]='(' then
Add1(S[i]);
If S[i]=')' then
begin
If pTop1.next<>nil then
x:=Del1
else
begin
ShowMessage('There is a mistake');
exit;
end;
end;
end;
If pTop1.next<>nil then
ShowMessage('There is a mistake')
else
ShowMessage('No mistakes');
end;
end.
Вопрос 25.
Постфиксная, префиксная, инфиксная записи выражения.
Преобразование выражения из инфиксной в префиксную и постфиксную формы.
Обычные арифметические выражения, используемые в повседневной практике и содержащие скобки, называют инфиксными выражениями, поскольку знак операции располагается между операндами. Порядок выполнения действий в таких выражениях определяется старшинством операций и скобками. Вычисление и компиляция таких выражений подразумевает их предварительный анализ с целью выявления порядка выполнения операций. Существуют формы записи арифметических выражений без скобок, в которых порядок действий задается порядком знаков операций в выражении. Такие формы записи называются польской или бесскобочной записью. Польская запись может быть префиксной, в которой знак операции предшествует операндам, и постфиксной, в которой знак операции следует за операндом. Вычисление и компиляция бесскобочных выражений оказывается проще, чем выражений со скобками, поскольку операции должны выполняться в порядке описания и предварительный анализ не требуется.
Алгоритм перевода из инфиксной записи в префиксную:
Просматриваем строку справа налево. Операнды помещаем в первый стек, скобки и знаки операций во второй. Если очередной элемент открывающаяся скобка, то она заносится во второй стек, если этот элемент закрывающаяся скобка, то последовательно применяем операции из второго стека к операндам из первого. Результаты заносим в первый стек, до тех пор пока во втором стеке не встретим открывающуюся скобку.
Если очередной элемент знак операции и верхний элемент второго стека тоже знак операции, то необходимо сравнить приоритет:
- если приоритет добавляемой операции выше, то мы ее добавляем во второй стек
- если он ниже или равен, то последовательно применяем операции из второго стека к операндам из первого, до тех пор пока не найдем операцию с меньшим приоритетом (по алгоритму такое невозможно). Либо мы дойдем до открывающейся скобки, либо мы опустошим второй стек.
Если мы просмотрели всю строку и во втором стеке есть элементы, то последовательно извлекаем их и применяем к операндам из первого стека
А теперь разберем на простом примере алгоритм перевода алгебраического выражения из инфиксной в постфиксную форму. При разборе нам понадобится два стека. Первый стек - временный, в него мы будем помещать знаки операций (временный стек). А во втором стеке мы будем формировать выражение в постфиксной форме (основной стек).
Если символ - число (или переменная), помещаем его в основной стек.
Если символ - знак операции ('+', '-', '/', '*'), то проверяем приоритет данной операции. Операции умножения и деления имеют наивысший приоритет (3), операции сложения и вычитания имеют меньший приоритет (2), самый низкий приоритет (1) имеет открывающая скобка.
Если временный стек пуст, или находящиеся в нем символы (а находиться в нем могут только знаки операций и открывающая скобка) имеют меньший приоритет, чем приоритет текущего символа, то помещаем текущий символ во временный стек.
Если символ, находящийся на вершине стека имеет приоритет, больший или равный приоритету текущего символа, то извлекаем символы из стека в основной стек до тех пор, пока не встретим символ с меньшим приоритетом. Встретив символ с меньшим приоритетом, мы прекращаем извлекать символы из временного стека, и ни в коем случае не забываем добавить во временный стек текущий символ. Переходим к предыдущему пункту.
Если символ - открывающая скобка, то помещаем ее во временный стек.
Если символ - закрывающая скобка, то извлекаем символы из временного стека в основной до тех пор, пока не встретим во временном стеке открывающую скобку, которую просто уничтожаем. Закрывающая скобка также уничтожается.
Если вся входная строка разобрана, но во временном стеке еще остаются знаки операций, мы должны просто извлечь их в основной стек, начиная с последнего символа.
function Prior(x:String): integer;
begin
case x[1] of
'(',')': Result := 1;
'+', '-': Result := 2;
'*', '/': Result := 3
else Result:=0;
end;
end;
procedure InfToPost(S:String);
var i:integer;
begin
for i:=1 to length(S) do
begin
If S[i] in ['0'..'9'] then
Add1(S[i]);
If S[i] in ['+','-','/','*'] then
If pTop2=nil then
Add2(S[i])
else
begin
If Prior(S[i])>Prior(pTop2.d)then
Add2(S[i])
else
begin
Repeat
Add1(pTop2.d);
x:=Del2;
until (pTop2=nil)or(Prior(S[i])>Prior(pTop2.d));
Add2(S[i]);
end;
end;
If S[i]='(' then
Add2(S[i]);
If S[i]=')' then
begin
Repeat
If pTop2.d='(' then
begin
x:=Del2;
break;
end;
Add1(pTop2.d);
x:=Del2;
until pTop2.next=nil;
end;
end;
If pTop2.next<>nil then
while pTop2.next<>nil do
begin
Add1(pTop2.d);
x:=Del2;
end;
end;
procedure InfToPost(S:String);
var i:integer;
begin
for i:=length(S) downto 1 do
begin
If S[i] in ['0'..'9'] then
Add1(S[i]);
If S[i] in ['+','-','/','*'] then
If pTop2=nil then
Add2(S[i])
else
begin
If Prior(S[i])>Prior(pTop2.d)then
Add2(S[i])
else
begin
Repeat
Add1(pTop2.d);
x:=Del2;
until (pTop2=nil)or(Prior(S[i])>Prior(pTop2.d));
Add2(S[i]);
end;
end;
If S[i]=')' then
Add2(S[i]);
If S[i]='(' then
begin
Repeat
If pTop2.d=')' then
begin
x:=Del2;
break;
end;
Add1(pTop2.d);
x:=Del2;
until pTop2.next=nil;
end;
end;
If pTop2.next<>nil then
while pTop2.next<>nil do
begin
Add1(pTop2.d);
x:=Del2;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
S:=Edit1.Text;
CreateSt1;
CreateSt2;
InfToPost(S);
pHelp:=pTop1;
while pHelp.next<>nil do
begin
S1:=S1+pHelp.d;
pHelp:=pHelp.next;
end;
Edit2.Text:=S1;
end;