Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.07.2012, 12:32   #1
tarasman11
Пользователь
 
Регистрация: 16.05.2012
Сообщений: 17
По умолчанию Проверить правильность расстановки круглых и квадратных скобок в выражениях

дана строка символов проверить правильность расстановки круглых и квадратных скобок в выражениях
tarasman11 вне форума Ответить с цитированием
Старый 04.07.2012, 12:47   #2
Mandrivnyk
Software Developer
Участник клуба
 
Аватар для Mandrivnyk
 
Регистрация: 01.03.2011
Сообщений: 1,098
По умолчанию

И в чем проблема?
Заводишь два счетчика и считаешь посимвольно.
Встречаешь открывающую скобку -- увеличиваешь счетчик, закрывающую уменьшаешь.
В любой точке строки счетчик не может быть отрицательным.
Еще надо условие на то, чтобы скобки не перекрывали друг друга -- вот так, к примеру:
( ( [ ) ] ) -- это неправильно.

Ну, и в конце строки счетчики должны быть равны нулю.
Болтовня ничего не стоит. Покажите мне код. (c) Linus Torvalds
Помог ответ? -- Поставьте отзыв.
Выражения особой благодарности в рублевом эквиваленте отправлять сюда --> R269634919062
Mandrivnyk вне форума Ответить с цитированием
Старый 05.07.2012, 09:42   #3
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

Эту задачу можно решить для любого вида скобок следующим образом:
Задаешь код скобок:
{ - 3 (плюс 3)
[ - 2 (плюс 2)
( - 1 (плюс 1)
) - -1 (минус 1)
] - -2 (минус 2)
} - -3 (минус 3)
Формируешь стек, в который вкладываешь всякую открывающуюся скобку (>0). Если скобка закрывающаяся (<0), то проверяешь стек. Если пуст, то ошибка иначе извлекаешь из стека число.
Складываешь извлеченное число с имеющимся. Если ноль, то все Ок иначе ошибка.
Это стандартный алгоритм.

Как то так ...
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 05.07.2012, 10:31   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

VktorR, сдаётся мне, что алгоритм описанный в вашем случае НЕ РАБОТОСПОСОБЕН (по крайней мере напрямую, так, как Вы его описали!)

Кроме того, раз уж мы про стек заговорили, кто нам мешает сделать его (стек) символьным и пихать встреченные открывающие скобки в него, а вытаскивать (с проверкой) из стека, когда в строке встречаются закрывающиеся скобки...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 05.07.2012, 12:18   #5
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Стек здесь излишняя бюрократия. Входящий поток символов уже можно рассматривать как стек, просто пропуская любые символы не являющиеся скобками. А если стек уже по сути есть, то зачем заводить еще один? Нафига два цикла когда можно воспользоваться одним?
Общую схему действий уже расписал Mandrivnyk - рабочая, я использовал подобную (только вместо квадратных скобок у меня были еще угловые < и >). Писал на c#, но алгоритм по сути тот же.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика

Последний раз редактировалось Utkin; 05.07.2012 в 12:21.
Utkin вне форума Ответить с цитированием
Старый 05.07.2012, 13:00   #6
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

ViktorR

Задаешь код скобок:
{ - 3 (плюс 3)
[ - 2 (плюс 2)
( - 1 (плюс 1)
) - -1 (минус 1)
] - -2 (минус 2)
} - -3 (минус 3)


{)))

:LOL:
Rififi вне форума Ответить с цитированием
Старый 05.07.2012, 13:23   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Utkin
А если стек уже по сути есть, то зачем заводить еще один? Нафига два цикла когда можно воспользоваться одним?
Да нету у Вас стека! А то, что Вы предлагаете - и есть организация стека с помощью строки (по сути строка - это массив символов, а стек легко может быть смоделирован с помощью массива и индекса(позиции) в этом массиве).


впрочем, по сути я с вами согласен. ещу одна дополнительная строчка быстро и удобно смоделирует стек (вот примерный набросок решения):
Код:
isError := false;
for i:=1 to Length(s) do
  if s[i] in ['[','(','{'] then Stek := Stek + s[i]
  else 
    if s[i] in [']',')','}'] then 
       if Length(Stek)=0 then 
            begin WriteLn('Ошибка в позиции ',i,' закрывающая скобка без открывающей'); isError :=  true; Break; 
            end
       else begin
          if Stek[Length(Stek)]<>s[i] then 
            begin WriteLn('Ошибка в позиции ',i,
                    ' закрывающая скобка не того типа, что была открывающая - ожидалась скобка ',Stek[Length(Stek)]); 
                isError :=  true; 
                Break; 
            end
          else {вроде всё в порядке - выкидываем последний символ из стека}
            Delete(Stek, Length(Stek), 1);
       end;
 
if (not isError) and (Length(Stek)=0) then
    WriteLn('Строка является корректным скобочным выражением!');
if (not isError) and (Length(Stek)>0) then
    WriteLn('Ошибка, не закрыты открывающие скобки!');
Serge_Bliznykov вне форума Ответить с цитированием
Старый 05.07.2012, 14:23   #8
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,645
По умолчанию

Небольшая поправка по строчке
Код:
if Stek[Length(Stek)]<>s[i]
условие обязательно выполнится при первом же символе кроме открывающих скобок (а нужно только для закрывающих скобок), поэтому лучше проверить ожидаемое сложным условием

Код:
if ((Stek[Length(Stek)]='(')and(s[i]<>')')) or
   ((Stek[Length(Stek)]='[')and(s[i]<>']')) or
   ((Stek[Length(Stek)]='{')and(s[i]<>'}')) then ...

Или же в стек добавлять обратные скобки, т.е. вместо
Код:
if s[i] in ['[','(','{'] then Stek := Stek + s[i] else
писать
Код:
if s[i] ='[' then Stek := Stek + ']' else
  if s[i] ='(' then Stek := Stek + ')' else
  if s[i] ='{' then Stek := Stek + '}'
  else
eoln вне форума Ответить с цитированием
Старый 05.07.2012, 15:34   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

eoln, я понял, о чём! Конечно же, когда мы встретили ЗАКРЫВАЮЩУЮ скобку, она НИКАК не будет равна открывающей!

это ошибка с моей стороны, эту мелочь надо учесть и исправить!


могу предложить такой вариант обхода:

Код:
const
  OtrkSkb = '[({';
  ZakrSkb = '])}'; {внимание! Порядок должен быть одинаковым!}
var
  i: integer;
  s, Stek: string;
  isError: boolean;
begin
  s :=
    '( vot { ([ 1+2 ] * 2) } )';

  isError := false;
  Stek := '';
  for i := 1 to Length(s) do
    if Pos(s[i], OtrkSkb) > 0 then Stek := Stek + s[i]
    else
      if Pos(s[i], ZakrSkb) > 0 then
        if Length(Stek) = 0 then
        begin WriteLn('Ошибка в позиции ', i, ' закрывающая скобка без открывающей'); isError := true; Break;
        end
        else begin
          if Pos(Stek[Length(Stek)], OtrkSkb) <> Pos(s[i], ZakrSkb) then
          begin WriteLn('Ошибка в позиции ', i,
              ' закрывающая скобка не того типа, что была открывающая - ожидалась скобка ', Stek[Length(Stek)]);
            isError := true;
            Break;
          end
          else {вроде всё в порядке - выкидываем последний символ из стека}
            Delete(Stek, Length(Stek), 1);
        end;

  if (not isError) and (Length(Stek) = 0) then
    WriteLn('Строка является корректным скобочным выражением!');
  if (not isError) and (Length(Stek) > 0) then
    WriteLn('Ошибка, не закрыты открывающие скобки!');

  readln
end.

Последний раз редактировалось Serge_Bliznykov; 05.07.2012 в 15:46.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 05.07.2012, 18:33   #10
tarasman11
Пользователь
 
Регистрация: 16.05.2012
Сообщений: 17
По умолчанию

напишите полностью правильный код пож
tarasman11 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа проверки правильности расстановки скобок glushara Помощь студентам 2 23.04.2012 02:49
Проверка правильности расстановки круглых скобок. torren108 Помощь студентам 7 11.12.2011 20:15
С++ Перегрузка квадратных скобок Namolem Помощь студентам 1 29.04.2010 02:45
Проверить равенство числа открывающих и закрывающих круглых скобок 010 Паскаль, Turbo Pascal, PascalABC.NET 6 18.05.2008 00:27
проверить правильность расстановки операторов begin и end Тёмка Помощь студентам 1 10.12.2007 13:07