Ребят помогите решить задачу))
вот сама задача:
1. Скобки
Составить обработку, которая проверяет корректность баланса скобок в арифметическом выражении, т.е.
что скобки установлены верно и правильно их вхождение, то есть если скобки так расположены [({})] , то это правильное вхождение, а вот [([) - неверное.
Входной параметр - Строка - арифметическое выражение;
Выходной параметр - "Верно"\"Не верно".
Использовать метод "Вычислить" нельзя
Вот как я решал!Но почему то не работает и ошибки нет
&НаКлиенте
Процедура ПроверитьСкобки(Команда)
стр = объект.Выражение;
ТекстОшибки = "";
ПозицияОшибки=0;
СкобкиРасставленыКорректно(Стр, ТекстОшибки , ПозицияОшибки);
КонецПроцедуры
&НаКлиенте
Функция СкобкиРасставленыКорректно(Стр, ТекстОшибки = "", ПозицияОшибки=0)
Перем к, с, ч, Стек;
ч=0;
Стек = "";
Для к = 1 По СтрДлина(Стр) Цикл
с = Сред(Стр, к, 1);
ч = Найти("({[", с);
Если ч > 0 Тогда
Стек = Сред(")}]", ч, 1) + Стек;
ИначеЕсли Найти(")}]", с) > 0 Тогда
Если Стек = "" Тогда
ПозицияОшибки = к;
ТекстОшибки = "Неверная закрывающая скобка: " + Лев(Стр, к - 1) + " """ + Сред(Стр, к, 1) + """ " + Сред(Стр, к + 1);
Возврат Ложь;
КонецЕсли;
Ожидается = Лев(Стек, 1);
Если Ожидается <> с Тогда
ПозицияОшибки = к;
ТекстОшибки = "Неверная закрывающая скобка: " + Лев(Стр, к - 1) + " """ + Сред(Стр, к, 1) + """ " + Сред(Стр, к + 1) + ". Ожидается """ + Ожидается + """ ";
Возврат Ложь;
КонецЕсли;
Стек = Сред(Стек, 2);
КонецЕсли;
КонецЦикла;
Если СтрДлина(Стек) > 0 Тогда
ПозицияОшибки = СтрДлина(Стр) + 1;
ТекстОшибки = "Отсутствует закрывающие скобки: " + Стек;
Возврат Ложь;
КонецЕсли;
ПозицияОшибки = 0;
ТекстОшибки = "Правильно";
Возврат Истина;
КонецФункции
ч = Найти("({[", с);
Процедура КнопкаВыполнитьНажатие(Кнопка)
Верно = Истина;
// ([{}])
// создаем таблицу значений скобок, какие есть скобки и в поле "Параметр" их группируем
лСтрока = СокрЛП(Строка);
ТЗСкобки = Новый ТаблицаЗначений;
ТЗСкобки.Колонки.Добавить("Параметр");
ТЗСкобки.Колонки.Добавить("СимволСкобки");
ТЗСкобки.Колонки.Добавить("КакаяСкобка");
Стр = ТЗСкобки.Добавить();
Стр.Параметр = 1;
Стр.СимволСкобки = "(";
Стр.КакаяСкобка = "Открывающая";
Стр = ТЗСкобки.Добавить();
Стр.Параметр = 1;
Стр.СимволСкобки = ")";
Стр.КакаяСкобка = "Закрывающая";
Стр = ТЗСкобки.Добавить();
Стр.Параметр = 2;
Стр.СимволСкобки = "[";
Стр.КакаяСкобка = "Открывающая";
Стр = ТЗСкобки.Добавить();
Стр.Параметр = 2;
Стр.СимволСкобки = "]";
Стр.КакаяСкобка = "Закрывающая";
Стр = ТЗСкобки.Добавить();
Стр.Параметр = 3;
Стр.СимволСкобки = "{";
Стр.КакаяСкобка = "Открывающая";
Стр = ТЗСкобки.Добавить();
Стр.Параметр = 3;
Стр.СимволСкобки = "}";
Стр.КакаяСкобка = "Закрывающая";
КолОткрывающихСкобок = 0;
КолСимволовВСтроке = СтрДлина(лСтрока);
// если количество символов (скобок) не четное то что-то не правильно
Если КолСимволовВСтроке/2 > Цел(КолСимволовВСтроке/2) Тогда
Сообщить("Не верно!");
Верно = Ложь;
Иначе
КолСимволов = 1;
// список значений - это список уже прочитаных и не закрытых скобок
СписокСкобок = Новый СписокЗначений;
Пока КолСимволов <> КолСимволовВСтроке Цикл
л = Сред(лСтрока, КолСимволов, 1); // берем символ
НайденоЗнач = ТЗСкобки.Найти(л);
Если НайденоЗнач = Неопределено Тогда
Сообщить("Не верно! В строке содержаться не только скобки!");
Верно = Ложь;
Прервать;
КонецЕсли;
Если НайденоЗнач.КакаяСкобка = "Закрывающая" и КолОткрывающихСкобок = 0 Тогда
Сообщить("Не верно!");
Верно = Ложь;
Прервать;
КонецЕсли;
Если НайденоЗнач.КакаяСкобка = "Открывающая" Тогда
КолОткрывающихСкобок = КолОткрывающихСкобок + 1;
КонецЕсли;
Если КолОткрывающихСкобок > КолСимволовВСтроке/2 Тогда
Сообщить("Не верно! В строке больше открывающих строк!");
Верно = Ложь;
Прервать;
КонецЕсли;
Если НайденоЗнач.КакаяСкобка = "Закрывающая" Тогда
ПоследняяСкобка = СписокСкобок[СписокСкобок.Количество()-1];
// проверяем по параметрам () {} []
Если ПоследняяСкобка.Значение.Параметр <> НайденоЗнач.Параметр Тогда
Сообщить("Не верно!");
Верно = Ложь;
Иначе
// удаляем открывающую скобку и закрывающую скобку не записываем
СписокСкобок.Удалить(СписокСкобок[СписокСкобок.Количество()-1]);
КонецЕсли;
Иначе
СписокСкобок.Добавить(НайденоЗнач);
КонецЕсли;
КолСимволов = КолСимволов + 1;
КонецЦикла;
Если Верно Тогда
Сообщить("Верно!");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
i | Выделяем код |
1. Вариант просто пока есть в строке подстроки "[]","{}","()" заменеям их на ""
2. Разновидность алгоритма польской нотации с использованием строки вместо стека.
Стр = "([()[]])";
МассивШаблонов = Новый Массив(3);
МассивШаблонов[0] = "[]"; МассивШаблонов[1] = "()"; МассивШаблонов[2] = "{}";
//Тупой вариант :
ЕстьЭлементыИзМассиваШаблонов = Истина;
пока ЕстьЭлементыИзМассиваШаблонов цикл
ЕстьЭлементыИзМассиваШаблонов = Ложь;
Для каждого ТекШаблон Из МассивШаблонов Цикл
Если Найти(Стр,ТекШаблон) Тогда
ЕстьЭлементыИзМассиваШаблонов = Истина;
Стр = СтрЗаменить(Стр,ТекШаблон,"");
КонецЕсли;
КонецЦикла;
КонецЦикла;
Сообщить(?(СтрДлина(Стр) = 0 ,"Все ок","You shall not pass!"));
//Типа умный
КвоСимволов = СтрДлина(Стр);
Стек = "";
ДлинаСтека = 0;
Для Инд = 1 По КвоСимволов Цикл
Символ = Сред(стр,инд,1);
Стек = Стек + Символ;
ДлинаСтека = ДлинаСтека + 1;
ПоследниекДваСивола = Прав(Стек,2);
Для каждого ТекШаблон Из МассивШаблонов Цикл
Если ТекШаблон = ПоследниекДваСивола Тогда
ДлинаСтека = ДлинаСтека - 2;
Стек = Лев(Стек,ДлинаСтека);
КонецЕсли;
КонецЦикла;
КонецЦикла;
Сообщить(?(СтрДлина(Стек) = 0 ,"Все ок","You shall not pass!"));
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua