Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/27: Рейтинг темы: голосов - 27, средняя оценка - 4.67
 Аватар для Black Angel
6 / 6 / 1
Регистрация: 26.01.2010
Сообщений: 216

Проверка правильности расстановок скобок

20.03.2011, 19:01. Показов 5429. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здраствуйте, нужна ваша помощ. Задание такое: проверить правильность расстановки скобок (), {}, [] в тексте, введенном пользователем. Что-то крутится в голове, но мои знания в Delphi не позволяют сделать ее( В принципе есть мысли: например в каком нибудь файле мы пишем текст.
Потом в форме подразумеваю будет два поля и кнопка. В первом поле будет текст из файла, потом жмем на кнопку, и в длугом поле уже исправленный текст.Буду рад вашей помощи

Добавлено через 2 минуты
Форму я еще содать могу, а вот в самом основном-не силен(
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.03.2011, 19:01
Ответы с готовыми решениями:

Нужно осуществить проверку правильности закрытия и открытия скобок в Delphi
Нужно осуществить проверку правильности закрытия и открытия скобок в Delphi, то есть - это правильное растравление скобок. А это или () на...

проверка правильности ввода
Как проверить что Edit введено положительное число, а не буква или другие символы?

Проверка правильности дешифровки
Собственно у меня есть программа, которая дешифрует фразы, которые ей вводит пользователь, выбирая их из данного словаря английских или...

9
4040 / 2652 / 582
Регистрация: 11.09.2009
Сообщений: 9,463
20.03.2011, 22:32
Цитата Сообщение от Black Angel Посмотреть сообщение
в длугом поле уже исправленный текст
Это вряд ли. Если не поставлена одна скобка, то, в общем случае, нет признаков, где её надо поставить. То же самое - как выбрать "лишнюю" скобку, которую надо удалить?

Проверка может быть только на равенство количества открывающих и закрывающих скобок каждого типа. Если в тексте нет чётких маркеров конца выражения со скобками (как например, в Delphi есть знак ";" или "end"), то проверить вообще можно только полностью весь текст.

Проверяется простым подсчётом количества скобок каждого типа. Открывающая скобка - счётчик +1, закрывающая - счётчик -1. В конце - если какой-либо счётчик не равен "0" - то есть ошибка.
Максимум, что можно - отметить в тексте последнюю скобку того типа, у которого счётчик не равен "0".

p.s.
Проверку надо дополнить контролем, что первая скобка каждого типа - открывающая, иначе не будут обнаружены ошибки вида )A+B(*C.
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
21.03.2011, 10:20
Типовое решение этой задачи - через стек. Предлагаю, например, такое решение:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, Windows;
 
const
  //Глубина стека. Т. е. максимальное количество элементов,
  //которое может поместиться в стек.
  N = 100;
  //Множество открывающих скобок.
  D1 = ['(', '[', '{'];
  //Множество закрывающих скобок.
  D2 = [')', ']', '}'];
 
type
  //Тип, описывающий стек.
  TStack = record
    //Указатель вершины стека. Это индекс последнего добавленного элемента.
    Pnt : Integer;
    //Контейнер данных стека.
    Data : array[1..N] of Char;
  end;
 
//Добавить в стек элемент.
function StackPush(var aStack : TStack; const aCh : Char) : Boolean;
begin
  StackPush := False;
  with aStack do begin
    if Pnt < High(Data) then begin
      //Индекс добавляемого элемента.
      Inc(Pnt);
      //Добавляем элемент в массив (т. е. в стек).
      Data[Pnt] := aCh;
      StackPush := True;
    end;
  end;
end;
 
//Взять из стека элемент.
function StackPop(var aStack : TStack; var aCh : Char) : Boolean;
begin
  StackPop := False;
  with aStack do begin
    if Pnt >= Low(Data) then begin
      aCh := Data[Pnt];
      Dec(Pnt);
      StackPop := True;
    end;
  end;
end;
 
//Для закрывающей скобки возвращает соответствующую открывающую скобку.
function GetOpen(const aCh : Char) : Char;
begin
  GetOpen := #0;
  case aCh of
    ')' : GetOpen := '(';
    ']' : GetOpen := '[';
    '}' : GetOpen := '{';
  else
    //Ошибка.
    Writeln('function GetOpen. Ошибка! Незарегистрированное значение.');
  end;
end;
 
//Исследование строки на предмет согласованности скобок.
function ParsePh(const aStr : String) : Integer;
var
  Stack : TStack;
  i, Res : Integer;
  Ch : Char;
begin
  //Инициализируем стек.
  Stack.Pnt := 0;
 
  Res := 1;
  for i := 1 to Length(aStr) do begin
    if aStr[i] in D1 then begin
      //Нашли открывающую скобку - добавляем её в стек.
      if not StackPush(Stack, aStr[i]) then begin
        Res := -1;
        Break;
      end;
    end else if aStr[i] in D2 then begin;
      //Нашли закрывающу скобку - берём элемент из вершины стека.
      if StackPop(Stack, Ch) then begin
        //Стек не пуст.
        if Ch <> GetOpen(aStr[i]) then begin
          //Взятая из вершины стека скобка не соответствует текущей закрывающей скобке.
          //Согласованность нарушена.
          Res := 0;
          Break;
        end;
      end else begin
        //Стек пуст. Значит нет соответствия для текущей закрывающей скобки.
        //Согласованность нарушена.
        Res := 0;
        Break;
      end;
    end;
  end;
 
  if Res = 1 then begin
    //Если стек не пуст - скобки не согласованы. Иначе - согласованы.
    if StackPop(Stack, Ch) then
      ParsePh := 0
    else
      ParsePh := 1
    ;
  end else
    ParsePh := Res
  ;
end;
 
var
  S : String;
begin
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
  
  repeat
    Writeln('Введите строку:');
    Readln(S);
    case ParsePh(S) of
      -1 : Writeln('Ошибка! Переполнение стека.');
      0  : Writeln('Скобки не согласованы.');
      1  : Writeln('Скобки согласованы.');
    end;
    Writeln('Повторить - Enter, выход - любой символ + Enter.');
    Readln(S);
  until S <> '';
end.
2
 Аватар для Black Angel
6 / 6 / 1
Регистрация: 26.01.2010
Сообщений: 216
21.03.2011, 18:24  [ТС]
Mawrat, а можно как-то переделать ее под форму?
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
21.03.2011, 21:07
GUI приложение:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
const
  //Глубина стека. Т. е. максимальное количество элементов,
  //которое может поместиться в стек.
  N = 100;
  //Множество открывающих скобок.
  D1 = ['(', '[', '{'];
  //Множество закрывающих скобок.
  D2 = [')', ']', '}'];
 
type
  //Тип, описывающий стек.
  TStack = record
    //Указатель вершины стека. Это индекс последнего добавленного элемента.
    Pnt : Integer;
    //Контейнер данных стека.
    Data : array[1..N] of Char;
  end;
 
//Добавить в стек элемент.
function StackPush(var aStack : TStack; const aCh : Char) : Boolean;
begin
  StackPush := False;
  with aStack do begin
    if Pnt < High(Data) then begin
      //Индекс добавляемого элемента.
      Inc(Pnt);
      //Добавляем элемент в массив (т. е. в стек).
      Data[Pnt] := aCh;
      StackPush := True;
    end;
  end;
end;
 
//Взять из стека элемент.
function StackPop(var aStack : TStack; var aCh : Char) : Boolean;
begin
  StackPop := False;
  with aStack do begin
    if Pnt >= Low(Data) then begin
      aCh := Data[Pnt];
      Dec(Pnt);
      StackPop := True;
    end;
  end;
end;
 
//Для закрывающей скобки возвращает соответствующую открывающую скобку.
function GetOpen(const aCh : Char) : Char;
begin
  GetOpen := #0;
  case aCh of
    ')' : GetOpen := '(';
    ']' : GetOpen := '[';
    '}' : GetOpen := '{';
  else
    //Ошибка.
    Writeln('function GetOpen. Ошибка! Незарегистрированное значение.');
  end;
end;
 
//Исследование строки на предмет согласованности скобок.
function ParsePh(const aStr : String) : Integer;
var
  Stack : TStack;
  i, Res : Integer;
  Ch : Char;
begin
  //Инициализируем стек.
  Stack.Pnt := 0;
 
  Res := 1;
  for i := 1 to Length(aStr) do begin
    if aStr[i] in D1 then begin
      //Нашли открывающую скобку - добавляем её в стек.
      if not StackPush(Stack, aStr[i]) then begin
        Res := -1;
        Break;
      end;
    end else if aStr[i] in D2 then begin;
      //Нашли закрывающу скобку - берём элемент из вершины стека.
      if StackPop(Stack, Ch) then begin
        //Стек не пуст.
        if Ch <> GetOpen(aStr[i]) then begin
          //Взятая из вершины стека скобка не соответствует текущей закрывающей скобке.
          //Согласованность нарушена.
          Res := 0;
          Break;
        end;
      end else begin
        //Стек пуст. Значит нет соответствия для текущей закрывающей скобки.
        //Согласованность нарушена.
        Res := 0;
        Break;
      end;
    end;
  end;
 
  if Res = 1 then begin
    //Если стек не пуст - скобки не согласованы. Иначе - согласованы.
    if StackPop(Stack, Ch) then
      ParsePh := 0
    else
      ParsePh := 1
    ;
  end else
    ParsePh := Res
  ;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  S : String;
begin
  S := Memo1.Text; //Или: S := Edit1.Text;
  
  case ParsePh(S) of
    -1 : ShowMessage('Ошибка! Переполнение стека.');
    0  : ShowMessage('Скобки не согласованы.');
    1  : ShowMessage('Скобки согласованы.');
  end;
end;
 
end.
2
 Аватар для Black Angel
6 / 6 / 1
Регистрация: 26.01.2010
Сообщений: 216
21.03.2011, 21:13  [ТС]
Спасибо большое за помощ)Сейчас про стек попольше почитаю чтобы окончательно понять что это такое и попробую что нибудь аналогичное сделать)Спасибо

---
Mawrat: Ок.
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
21.03.2011, 21:28
Идея алгоритма на стеке вот в чём. - Мы проходим строку слева-направо. Если встречается открывающая скобка - помещаем её в стек. Если встречается закрывающая скобка, то:
- Пытаемся извлечь из вершины стека скобку.
- Если на вершине оказалась соответствующая открывающая скобка, т. е. "(" для ")" или "{" для "}" и т. д. - значит согласованность не нарушена.
- Во всех остальных случаях согласованность нарушена:
-- Если стек оказался пуст. - Т. е., на исследованном участке закрывающих скобок оказалось больше, чем открывающих.
-- Если на вершине стека оказалась не соответствующая скобка, например: "(" для "}".
-- Согласованность также нарушена, если после прохода всей строки стек оказался непустым. - Т. е. открывающих скобок оказалось больше, чем закрывающих.
1
 Аватар для Black Angel
6 / 6 / 1
Регистрация: 26.01.2010
Сообщений: 216
21.03.2011, 21:33  [ТС]
Спасибо большое за объяснение), но окончательно я пойму принцип если сам попробую стеком воспользоваться)

---
Mawrat: Это верно - для привыкания к стеку надо погонять какие-нибудь программы с ним. Для начала можно реализовать стек, записать в него группу элементов, потом - читать из него элементы до тех пор, пока он не пуст и тут же эти элементы распечатывать. И пр.
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
22.03.2011, 00:25
Ещё пояснения.
Например, задана строка: '(((){{}()})[()])'
- всего 16 символов. Во время обработки этой строки будет происходить следующее:
Очередной символ Операция Содержимое стека Проверка соответствия
01 ( Стек <- ( ( -
02 ( Стек <- ( (( -
03 ( Стек <- ( ((( -
04 ) Стек -> ( (( '(' и ')' - согласованы
05 { Стек <- { (({ -
06 { Стек <- { (({{ -
07 } Стек -> { (({ '{' и '}' - согласованы
08 ( Стек <- ( (({( -
09 ) Стек -> ( (({ '(' и ')' - согласованы
10 } Стек -> { (( '{' и '}' - согласованы
11 ) Стек -> ( ( '(' и ')' - согласованы
12 [ Стек <- [ ([ -
13 ( Стек <- ( ([( -
14 ) Стек -> ( ([ '(' и ')' - согласованы
15 ] Стек -> [ ( '[' и ']' - согласованы
16 ) Стек -> ( Стек пуст. '(' и ')' - согласованы
Пример с несогласованными скобками:
Задана строка: '(((){{}(}))[()])'
Очередной символ Операция Содержимое стека Проверка соответствия
01 ( Стек <- ( ( -
02 ( Стек <- ( (( -
03 ( Стек <- ( ((( -
04 ) Стек -> ( (( '(' и ')' - согласованы
05 { Стек <- { (({ -
06 { Стек <- { (({{ -
07 } Стек -> { (({ '{' и '}' - согласованы
08 ( Стек <- ( (({( -
09 } Стек -> ( (({ '(' и '}' - не согласованы - выход из цикла
2
 Аватар для Black Angel
6 / 6 / 1
Регистрация: 26.01.2010
Сообщений: 216
22.03.2011, 12:11  [ТС]
Все я понял)))Спасобо большое))

---
Mawrat: Пожалуйста.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.03.2011, 12:11
Помогаю со студенческими работами здесь

Проверка правильности имени
Люди помогите написать программу, для проверки правильности вводимого имени в поле Edit при нажатии кнопки Button. Условия: 1) Имя...

Проверка правильности ввода даты
Ввожу дату в Edit, проверка идёт правильно, но он не учитывает нули, скрин приложил. Как поставить ограничение, по типу день-2 символа,...

Поток: проверка правильности ввода числа
Создайте приложение, которое в фоновом режиме проверяет правильно введенные числа. На главной форме разместите два многострочных редактора....

Проверка правильности ввода в поле Edit
как сделать проверку правильности ввода в поле Edit, чтобы исключить недопустимые символы? Нужно чтобы при вводе в поле Edit1 любых...

Проверка правильности ввода, очищение полей
Здравствуйте, помогите, пожалуйста, доработать приложение для конвертации валюты в рубли. Нужно следующее: 1.При вводе данных в одно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru