Заказы на доработку 1С (сервис удаленной работы)

Хранилище

База знаний
Неназначенных незавершенных заказов: 2, свеженьких 1
Бесплатные отчеты, обработки, конфигурации, внешние компоненты для 1С Статьи, описание работы, методики по работе с 1С

Здравствуйте, гость ( Вход | Зарегистрироваться )



> Задача "скобки"          
Астахов Подменю пользователя
сообщение 21.03.15, 12:24
Сообщение #1

Общительный
**
Группа: Пользователи
Сообщений: 27
Спасибо сказали: 0 раз
Рейтинг: 0

Ребят помогите решить задачу))
вот сама задача:
1. Скобки
Составить обработку, которая проверяет корректность баланса скобок в арифметическом выражении, т.е.
что скобки установлены верно и правильно их вхождение, то есть если скобки так расположены [({})] , то это правильное вхождение, а вот [([) - неверное.
Входной параметр - Строка - арифметическое выражение;
Выходной параметр - "Верно"\"Не верно".
Использовать метод "Вычислить" нельзя

Вот как я решал!Но почему то не работает и ошибки нет
&НаКлиенте
Процедура ПроверитьСкобки(Команда)
    стр = объект.Выражение;
    ТекстОшибки = "";
    ПозицияОшибки=0;
    СкобкиРасставленыКорректно(Стр, ТекстОшибки , ПозицияОшибки);
    КонецПроцедуры


&НаКлиенте
Функция СкобкиРасставленыКорректно(Стр, ТекстОшибки = "", ПозицияОшибки=0)
    Перем к, с, ч, Стек;
    
    ч=0;
    Стек = "";
    
    Для к = 1 По СтрДлина(Стр) Цикл
        с = Сред(Стр, к, 1);
        ч = Найти("({[", с);
        Если ч > 0 Тогда
            Стек = Сред(")}]", ч, 1) + Стек;
        ИначеЕсли Найти(")}]", с) > 0  Тогда
            Если Стек = "" Тогда
                ПозицияОшибки = к;
                ТекстОшибки = "Неверная закрывающая скобка: " + Лев(Стр, к - 1) + " """ + Сред(Стр, к, 1) + """ " + Сред(Стр, к + 1);
                Возврат Ложь;
            КонецЕсли;
            Ожидается = Лев(Стек, 1);
            Если Ожидается <> с Тогда  
                ПозицияОшибки = к;
                ТекстОшибки = "Неверная закрывающая скобка: " + Лев(Стр, к - 1) + " """ + Сред(Стр, к, 1) + """ " + Сред(Стр, к + 1) + ". Ожидается """ + Ожидается + """ ";
                Возврат Ложь;
            КонецЕсли;
            Стек = Сред(Стек, 2);
        КонецЕсли;
    КонецЦикла;
    Если СтрДлина(Стек) > 0 Тогда
        ПозицияОшибки = СтрДлина(Стр) + 1;
        ТекстОшибки = "Отсутствует закрывающие скобки: " + Стек;
        Возврат Ложь;
    КонецЕсли;
    
    ПозицияОшибки = 0;
    ТекстОшибки = "Правильно";
    Возврат Истина;
    
КонецФункции

Zaval Подменю пользователя
сообщение 22.03.15, 18:09
Сообщение #2

Крутой
Иконка группы
Группа: Местный
Сообщений: 1994
Из: Киева и окрестностей
Спасибо сказали: 406 раз
Рейтинг: 0

Цитата(Астахов @ 21.03.15, 12:24) *
ч = Найти("({[", с);

Вот здесь Вы ищете подстроку, три скобки подряд и именно в таком поряке. В реальной формуле они могут быть разделены символами и еще и вложенность иметь.
Но еще и сам алгоритм нерабочий.
Нужно просто перебирать символ за символом и вести учет найденных скобок в списке значений. Открывающие - записывать, если скобка закрывающая и правильная по типу - вычеркивать. После перебора правильной формулы список значений будет пуст. ! Строки кода, удаляющие значение из списка запихнуть в ПопыткаИсключение. И не забудьте о знаке равенства, по нему нужно "подвести итоги" и начать с пустого СЗ.

Сообщение отредактировал Zaval - 22.03.15, 18:13

alyonchik Подменю пользователя
сообщение 30.06.15, 6:01
Сообщение #3

Молчаливый
*
Группа: Пользователи
Сообщений: 1
Спасибо сказали: 0 раз
Рейтинг: 0

Процедура КнопкаВыполнитьНажатие(Кнопка)
    
    Верно = Истина;
    
    //  ([{}])
    
    // создаем таблицу значений скобок, какие есть скобки и в поле "Параметр" их группируем
    лСтрока = СокрЛП(Строка);
    
    ТЗСкобки = Новый ТаблицаЗначений;
    
    ТЗСкобки.Колонки.Добавить("Параметр");
    ТЗСкобки.Колонки.Добавить("СимволСкобки");
    ТЗСкобки.Колонки.Добавить("КакаяСкобка");
    
    Стр = ТЗСкобки.Добавить();
    Стр.Параметр         = 1;
    Стр.СимволСкобки     = "(";
    Стр.КакаяСкобка     = "Открывающая";
    
    Стр = ТЗСкобки.Добавить();
    Стр.Параметр         = 1;
    Стр.СимволСкобки     = ")";
    Стр.КакаяСкобка     = "Закрывающая";
    
    Стр = ТЗСкобки.Добавить();
    Стр.Параметр         = 2;
    Стр.СимволСкобки     = "[";
    Стр.КакаяСкобка     = "Открывающая";
    
    Стр = ТЗСкобки.Добавить();
    Стр.Параметр         = 2;
    Стр.СимволСкобки     = "]";
    Стр.КакаяСкобка     = "Закрывающая";
    
    Стр = ТЗСкобки.Добавить();
    Стр.Параметр         = 3;
    Стр.СимволСкобки     = "{";
    Стр.КакаяСкобка     = "Открывающая";
    
    Стр = ТЗСкобки.Добавить();
    Стр.Параметр         = 3;
    Стр.СимволСкобки     = "}";
    Стр.КакаяСкобка     = "Закрывающая";
    
    КолОткрывающихСкобок = 0;
    
    КолСимволовВСтроке = СтрДлина(лСтрока);
    
    // если количество символов (скобок) не четное то что-то не правильно
    Если КолСимволовВСтроке/2 > Цел(КолСимволовВСтроке/2) Тогда
        Сообщить("Не верно!");    
        Верно = Ложь;
    Иначе
        КолСимволов = 1;
        
        // список значений - это список уже прочитаных и не закрытых скобок
        СписокСкобок = Новый СписокЗначений;
        
        Пока КолСимволов <> КолСимволовВСтроке Цикл
            
            л = Сред(лСтрока, КолСимволов, 1); // берем символ
            
            НайденоЗнач = ТЗСкобки.Найти(л);
            
            Если НайденоЗнач = Неопределено Тогда
                Сообщить("Не верно! В строке содержаться не только скобки!");
                Верно = Ложь;
                Прервать;    
            КонецЕсли;
            
            Если НайденоЗнач.КакаяСкобка = "Закрывающая" и КолОткрывающихСкобок = 0 Тогда
                Сообщить("Не верно!");    
                Верно = Ложь;
                Прервать;
            КонецЕсли;
            
            Если НайденоЗнач.КакаяСкобка = "Открывающая" Тогда
                КолОткрывающихСкобок = КолОткрывающихСкобок + 1;
            КонецЕсли;
            
            Если  КолОткрывающихСкобок > КолСимволовВСтроке/2 Тогда
                Сообщить("Не верно! В строке больше открывающих строк!");
                Верно = Ложь;
                Прервать;    
            КонецЕсли;
            
            
            Если  НайденоЗнач.КакаяСкобка = "Закрывающая" Тогда
                ПоследняяСкобка = СписокСкобок[СписокСкобок.Количество()-1];
                
                // проверяем по параметрам () {} []
                Если ПоследняяСкобка.Значение.Параметр <> НайденоЗнач.Параметр Тогда
                    Сообщить("Не верно!");
                    Верно = Ложь;
                Иначе
                    // удаляем открывающую скобку и закрывающую скобку не записываем
                    СписокСкобок.Удалить(СписокСкобок[СписокСкобок.Количество()-1]);
                КонецЕсли;
            Иначе
                СписокСкобок.Добавить(НайденоЗнач);
            КонецЕсли;
            
            КолСимволов = КолСимволов + 1;
        КонецЦикла;
        
        Если Верно Тогда
            Сообщить("Верно!");
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры



У меня с этим кодом работает)


 i 

Выделяем код
 


Сообщение отредактировал Vofka - 30.06.15, 8:10

TipsyKID Подменю пользователя
сообщение 30.06.15, 11:07
Сообщение #4

Оратор
Иконка группы
Группа: Местный
Сообщений: 413
Из: Киев
Спасибо сказали: 161 раз
Рейтинг: 0

1. Вариант просто пока есть в строке подстроки "[]","{}","()" заменеям их на ""
2. Разновидность алгоритма польской нотации с использованием строки вместо стека.

  Стр = "([()[]])";
    МассивШаблонов = Новый Массив(3);
    МассивШаблонов[0] = "[]";    МассивШаблонов[1] = "()";    МассивШаблонов[2] = "{}";

    //Тупой вариант :
   ЕстьЭлементыИзМассиваШаблонов = Истина;
    
    пока ЕстьЭлементыИзМассиваШаблонов цикл
      ЕстьЭлементыИзМассиваШаблонов = Ложь;
      Для каждого ТекШаблон Из МассивШаблонов Цикл
           Если Найти(Стр,ТекШаблон) Тогда
              ЕстьЭлементыИзМассиваШаблонов = Истина;
             Стр = СтрЗаменить(Стр,ТекШаблон,"");
         КонецЕсли;
      КонецЦикла;  
    КонецЦикла;
    Сообщить(?(СтрДлина(Стр) = 0 ,"Все ок","You shall not pass!"));
    
    //Типа умный
    КвоСимволов = СтрДлина(Стр);
    Стек = "";
    ДлинаСтека = 0;
    Для Инд = 1 По  КвоСимволов Цикл
        Символ = Сред(стр,инд,1);
        Стек = Стек + Символ;
        ДлинаСтека = ДлинаСтека + 1;
        ПоследниекДваСивола = Прав(Стек,2);
        Для каждого ТекШаблон Из МассивШаблонов Цикл
            Если ТекШаблон = ПоследниекДваСивола Тогда
                ДлинаСтека = ДлинаСтека - 2;
                Стек = Лев(Стек,ДлинаСтека);
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
    Сообщить(?(СтрДлина(Стек) = 0 ,"Все ок","You shall not pass!"));


Signature
Специалист : Технологическая платформа 8.х, Бухгалтерия для Украины, Управление торговлей для Украины, Зарплата и Управление Персоналом для Украины

andr_andrey Подменю пользователя
сообщение 30.06.15, 15:00
Сообщение #5

Почти ветеран
Иконка группы
Группа: Местный
Сообщений: 626
Спасибо сказали: 166 раз
Рейтинг: 130.8

Цитата(TipsyKID @ 30.06.15, 12:07) *
1. Вариант просто пока есть в строке подстроки "[]","{}","()" заменеям их на ""
2. Разновидность алгоритма польской нотации с использованием строки вместо стека.
...

Насколько я понял из условия задачи, "арифметическое выражение" - нечто более сложное чем последовательность исключительно скобок.
Автору темы не мешало бы показать примеры входных данных, чтобы не вводить народ в ненужные поиски.


Signature
#define private public
enum BOOL { FALSE, TRUE, FILENOTFOUND } is made my day

TipsyKID Подменю пользователя
сообщение 30.06.15, 19:45
Сообщение #6

Оратор
Иконка группы
Группа: Местный
Сообщений: 413
Из: Киев
Спасибо сказали: 161 раз
Рейтинг: 0

Цитата(andr_andrey @ 30.06.15, 15:00) *
Насколько я понял из условия задачи, "арифметическое выражение" - нечто более сложное чем последовательность исключительно скобок.
Автору темы не мешало бы показать примеры входных данных, чтобы не вводить народ в ненужные поиски.

Это не играет значимой роли - почитайте об алгоритме "польской нотации" .
Он просто разбрасывает по стеку операнды и знаки операции.
Не важно, будет ли это сложное арифметическое выражение или просто скобки. Мухи с котлетами разделяются в два стека и поэтапно обрабатываются.


Signature
Специалист : Технологическая платформа 8.х, Бухгалтерия для Украины, Управление торговлей для Украины, Зарплата и Управление Персоналом для Украины

andr_andrey Подменю пользователя
сообщение 01.07.15, 9:02
Сообщение #7

Почти ветеран
Иконка группы
Группа: Местный
Сообщений: 626
Спасибо сказали: 166 раз
Рейтинг: 130.8

Цитата(TipsyKID @ 30.06.15, 20:45) *
Это не играет значимой роли - почитайте об алгоритме "польской нотации" .
Он просто разбрасывает по стеку операнды и знаки операции.
Не важно, будет ли это сложное арифметическое выражение или просто скобки. Мухи с котлетами разделяются в два стека и поэтапно обрабатываются.

С "польскую нотацией" знаком.
Я выразил сомнение, поймёт ли автор, что ваш пример - это возможно только часть решения.


Signature
#define private public
enum BOOL { FALSE, TRUE, FILENOTFOUND } is made my day

Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 18.04.24, 6:27
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!