Задача. Вводится символьная строка, в которой записано некоторое (арифметическое) выражение, использующее скобки трех типов: (), [] и {}. Проверить, правильно ли расставлены скобки.
Например, выражение ()[{(){}}] - правильное, потому что каждой открывающей скобке соответствует закрывающая, и вложенность скобок не нарушается. Выражения
[()
[[[()
[()}
)(
([)]
неправильные. В первых трех есть непарные скобки, а в последних двух не соблюдается вложенность скобок.
Задачи, в которых важна вложенность объектов, удобно решать с помощью стека.
Алгоритм решения задачи.
Строка просматривается слева направо.
Если очередной символ - открывающая скобка, нужно поместить ее на вершину стека.
Если это закрывающая скобка, то проверяем, что лежит на вершине стека: если стек не пуст и на его вершине соответствующая открывающая скобка, то ее нужно просто удалить из стека; если стек пуст или на вершине лежит открывающая скобка другого типа, выражение неверное и нужно закончить просмотр.
Если в конце обработки строки стек остался не пуст, то выражение также неверное.
Советы по организации программы.
1) Стек сделать состоящим из переменных типа char:
Const
N=255;
Type
stack=array[1..N] of char;
2) Ввести строковые константы L и R, которые будут содержать все вида открывающих и соответствующих закрывающих скобок:
Const
L='([{';
R=')]}';
3) В основной программе использовать переменные:
Var
St : stack; {стек}
Top,i : byte; {вершина стека и счетчик циклов}
s : string; {исходная строка}
b : char; {для удаления символа из стека}
err : boolean; {будет сигнализировать об ошибке}
4) Перебор символов строки:
For i:=1 to length(s) do
begin
...
end;
5)Проверка того, что очередной символ - открывающая скобка:
If pos(s[i],L)>0 then ...
Проверка того, что очередной символ - закрывающая скобка:
If pos(s[i],R)>0 then ...
6) Проверка, что закрывающая скобка и символ на вершине стека - скобки одного типа:
OutSt(b);
if pos(s[i],R)<>pos(b,L) then err:= true;
7) В начале программы переменной err присваиваем значение Fasle. При обнаружении ошибки записываем в нее значение True
err:=True;
Если при обработке текущего символа обнаружено, что выражение неверное (значение переменной err - True), нужно закончить цикл досрочно с помощью оператора break.
If err then break;
8) В конце программы остается вывести результат на экран:
If Empty and not(err)
then writeln('Выражение правильное')
else writeln('Выражение неправильное');
9) Работа с самим стеком (процедуры и функции) была подробно описана на предыдущем занятии.
Комментариев нет:
Отправить комментарий