|
Задача со скобкаим | ☑ | ||
---|---|---|---|---|
0
Sv4org
20.12.16
✎
21:24
|
Составить обработку, которая проверяет корректность баланса скобок в арифметическом выражении, т.е. что скобки установлены верно и правильно их вхождение, то есть если скобки так расположены [({})] , то это правильное вхождение, а вот [([) - неверное.
Входной параметр - Строка - арифметическое выражение; Выходной параметр - "Верно"\"Не верно". Использовать метод "Вычислить" нельзя. |
|||
1
Sv4org
20.12.16
✎
21:24
|
Подскажите пожалуйста как это решить
|
|||
2
Мимохожий Однако
20.12.16
✎
21:30
|
Перебирай последовательно и считай скобки.
|
|||
3
butterbean
20.12.16
✎
21:31
|
Перебирай посимвольно и запоминай в массив открытые скобки, и убирай их оттуда по мере того, как попадутся закрытые
|
|||
4
Fragster
гуру
20.12.16
✎
21:33
|
2000 рублей
|
|||
5
Garykom
гуру
20.12.16
✎
21:35
|
(0) Задача имеет много решений, правильные это нечто вроде https://ru.wikipedia.org/wiki/Синтаксический_анализ можно восходящий.
А тупое это
|
|||
6
Garykom
гуру
20.12.16
✎
21:37
|
(5)+ сорри за очепятки
|
|||
7
Garykom
гуру
20.12.16
✎
21:38
|
Гы кто ответит не запуская сколько у меня всего ошибок в (5) и сколько разных видов ошибок?
|
|||
8
Sv4org
20.12.16
✎
21:50
|
Ну суть примерно понял, вот что получилось, не знаю правильно или нет
Процедура КнопкаВыполнитьНажатие(Кнопка) Верно = Истина; // ([{}]) // создаем таблицу значений скобок, какие есть скобки и в поле "Параметр" их группируем лСтрока = СокрЛП("Строка"); ТЗСкобки = Новый ТаблицаЗначений; ТЗСкобки.Колонки.Добавить("Параметр"); ТЗСкобки.Колонки.Добавить("СимволСкобки"); ТЗСкобки.Колонки.Добавить("КакаяСкобка"); Стр = ТЗСкобки.Добавить(); Стр.Параметр = 1; Стр.СимволСкобки = "("; Стр.КакаяСкобка = "Открывающая"; Стр = ТЗСкобки.Добавить(); Стр.Параметр = 1; Стр.СимволСкобки = ")"; Стр.КакаяСкобка = "Закрывающая"; Стр = ТЗСкобки.Добавить(); Стр.Параметр = 2; Стр.СимволСкобки = "["; Стр.КакаяСкобка = "Открывающая"; Стр = ТЗСкобки.Добавить(); Стр.Параметр = 2; Стр.СимволСкобки = "]"; Стр.КакаяСкобка = "Закрывающая"; Стр = ТЗСкобки.Добавить(); Стр.Параметр = 3; Стр.СимволСкобки = "{"; Стр.КакаяСкобка = "Открывающая"; Стр = ТЗСкобки.Добавить(); Стр.Параметр = 3; Стр.СимволСкобки = "}"; Стр.КакаяСкобка = "Закрывающая"; КолОткрывающихСкобок = 0; КолСимволовВСтроке = СтрДлина(лСтрока); // если количество символов (скобок) не четное то что-то не правильно Если КолСимволовВСтроке/2 > Цел(КолСимволовВСтроке/2) Тогда Сообщить("Не верно!"); Верно = Ложь; Иначе КолСимволов = 1; // список значений - это список уже прочитаных и не закрытых скобок СписокСкобок = Новый СписокЗначений; Пока КолСимволов <> КолСимволовВСтроке Цикл л = Сред(лСтрока, КолСимволов, 1); // берем символ НайденоЗнач = ТЗСкобки.Найти(л); Если НайденоЗнач = Неопределено Тогда Сообщить("Не верно! В строке содержаться не только скобки!"); Верно = Ложь; Прервать; КонецЕсли; Если НайденоЗнач.КакаяСкобка = "Закрывающая" и КолОткрывающихСкобок = 0 Тогда Сообщить("Не верно!"); Верно = Ложь; Прервать; КонецЕсли; Если НайденоЗнач.КакаяСкобка = "Открывающая" Тогда КолОткрывающихСкобок = КолОткрывающихСкобок + 1; КонецЕсли; Если КолОткрывающихСкобок > КолСимволовВСтроке/2 Тогда Сообщить("Не верно! В строке больше открывающих строк!"); Верно = Ложь; Прервать; КонецЕсли; Если НайденоЗнач.КакаяСкобка = "Закрывающая" Тогда ПоследняяСкобка = СписокСкобок[СписокСкобок.Количество()-1]; // проверяем по параметрам () {} [] Если ПоследняяСкобка.Значение.Параметр <> НайденоЗнач.Параметр Тогда Сообщить("Не верно!"); Верно = Ложь; Иначе // удаляем открывающую скобку и закрывающую скобку не записываем СписокСкобок.Удалить(СписокСкобок[СписокСкобок.Количество()-1]); КонецЕсли; Иначе СписокСкобок.Добавить(НайденоЗнач); КонецЕсли; КолСимволов = КолСимволов + 1; КонецЦикла; Если Верно Тогда Сообщить("Верно!"); КонецЕсли; КонецЕсли; КонецПроцедуры Подскажите только как сделать это в обработке? какие реквизиты нужны или ТЧ? Как это вообще должно работать? |
|||
9
НП
20.12.16
✎
22:10
|
(0) Строгое решение состоит в преобразовании в польскую (постфиксную) запись. Все это широко обсуждалось лет 50 тому назад.
В книге Генератор компиляторов У Маккимана и др. на стр. 52 в разделе "Деревья, стеки и польская запись приводится" теоретической обоснование компиляции арифметического выражения. |
|||
10
NorthWind
20.12.16
✎
22:29
|
(0) рекурсия. Сканируем строку слева направо. Когда обнаруживается открывающаяся скобка - вызываем себя же, передавая номер следующего после открывающейся скобки символа и тип этой скобки (квадратная, круглая и т.д.). Соответственно сканируем уже начиная с этого символа и т.д. Выход из процедуры на уровень выше происходит, когда встретится закрывающая скобка такого же типа, как была передана, или когда строка окончится.
. Еще должна быть глобальная по отношению к процедуре переменная типа "счетчика ссылок". Изначально она инициализируется нулем. Встретили открывающую скобку - увеличиваем на 1, закрывающую - уменьшили на 1. . Если выражение корректно, то по окончании сканирования значение этой переменной будет 0. Если скобки расположены криво или их количество не соответствует действительности, то значение будет ненулевое. |
|||
11
NorthWind
20.12.16
✎
22:32
|
(9) польскую запись есть смысл мутить, если нужно делать полноценный разбор выражений с арифметическими и прочими действиями. Если просто посчитать скобки и корректность их открытия-закрытия - то достаточно (10).
|
|||
12
Fragster
гуру
20.12.16
✎
22:34
|
Зачем рекурсия? Цикл и стек из массива.
|
|||
13
NorthWind
20.12.16
✎
22:39
|
(12) Если бояться переполнения стека, то таки да :)
|
|||
14
NorthWind
20.12.16
✎
22:40
|
хотя можно просто поставить ограничение на количество вложений скобок
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |