Имя: Пароль:
1C
 
Как проверить корректность расстановки скобок в выражении?
0 Владислав_
startinpro
 
23.04.21
12:21
Проверить корректность расстановки скобок в арифметическом выражении.
Выражение задается как строковый входной параметр функции и может содержать произвольное количество круглых скобок.
Функция должна возвращать одну строчку: "правильно" или "неправильно".
1 Mikeware
 
23.04.21
12:22
срочно скажи, что не получается.
2 Mikeware
 
23.04.21
12:23
да, и ты волшебное слово забыл добавить - "бегоммлять!"©
3 Garykom
 
гуру
23.04.21
12:24
(0) Попытка ... Вычислить(...)
4 Mikeware
 
23.04.21
12:25
(3) само выражение может быть бессмысленным. его только скобки интересуют.
ну обычная задачка школьная...
5 d_monah
 
23.04.21
12:25
(0) А вы знаете,так можно,попробуйте.Если не получится ,сообщите,попробуем по другому
6 mikecool
 
23.04.21
12:27
Функция ВернутьПравильноИлиНеправильно()
  Возврат "Правильно" Или "Неправильно";
КонецФункции
7 fisher
 
23.04.21
12:27
Возврат СтрЧислоВхождений(ИсходнаяСтрока, "(") = СтрЧислоВхождений(ИсходнаяСтрока, ")");
8 Mikeware
 
23.04.21
12:28
(7) это всего лишь необходимое условие
9 mikecool
 
23.04.21
12:28
(7) результат возврата не тот )
10 fisher
 
23.04.21
12:28
(8) Согласен
11 Garykom
 
гуру
23.04.21
12:30
(4) заменить все кроме скобок на хрень но вычисляемую и Попытка Вычислить
12 fisher
 
23.04.21
12:30
Придется посимвольным обходом с проверкой на отсутствие закрывающих скобок без открывающих
13 Garykom
 
гуру
23.04.21
12:31
(7) Добавить что нет бессмысленных скобок типа "()" и пойдет
14 Garykom
 
гуру
23.04.21
12:32
(13)+ а и еще что нет внешних скобок хотя и парных типа "..)..(.."
15 Mikeware
 
23.04.21
12:33
(12) ну ,чтоб количество открытыъ подскобочных выражений всегда было неотрицательным.
интересно, а регулярками как такое сделать?
16 Garykom
 
гуру
23.04.21
12:33
(14)+ Достаточно проверки что первая скобка слева "(" а справа последняя это ")"
17 fisher
 
23.04.21
12:34
(15) Не хочу даже думать. От регулярок чаще больше зла, чем добра :)
18 fisher
 
23.04.21
12:34
(16) Недостаточно
19 RomanYS
 
23.04.21
12:35
(15) давайте усложним задачу, (0) надо решить в запросе)
20 Mikeware
 
23.04.21
12:35
(17) но ведь один хрен это у нас конечный автомат получается?
21 RomanYS
 
23.04.21
12:35
(16)
())(()
22 Mikeware
 
23.04.21
12:36
(19) в запросе - это к ильдаровичу.
23 Владислав_
startinpro
 
23.04.21
12:37
ЛКруглаяСкобка = 0;
    ПКвадратнаяСкобка = 0;
    ЛКвадратнаяСкобка = 0;
    ПФигурнаяСкобка = 0;
    ЛФигурнаяСкобка = 0;
    ПУгловаяСкобка = 0;
    ЛУгловаяСкобка = 0;
    ТестоваяСтрока = "";
    ВвестиСтроку(ТестоваяСтрока, "Введите выражение");
    Для Буква = 1 По СтрДлина(ТестоваяСтрока) Цикл
    
    Если Буква = "(" Тогда
        ПКруглаяСкобка = ПКруглаяСкобка + 1;        
    
    ИначеЕсли Буква = ")" Тогда
        ЛКруглаяСкобка = ЛКруглаяСкобка + 1;
    
    ИначеЕсли Буква = "[" Тогда
        ПКвадратнаяСкобка = ПКвадратнаяСкобка + 1;
    ИначеЕсли Буква = "]" Тогда
        ЛКвадратнаяСкобка = ЛКвадратнаяСкобка + 1;
    ИначеЕсли Буква = "{" Тогда
        ПФигурнаяСкобка = ПФигурнаяСкобка + 1;
    ИначеЕсли Буква = "}" Тогда
        ЛФигурнаяСкобка = ЛФигурнаяСкобка + 1;
    ИначеЕсли Буква = "<" Тогда
        ПУгловаяСкобка = ПУгловаяСкобка + 1;    
    Иначе Буква = ">" Тогда
        ЛУгловаяСкобка = ЛУгловаяСкобка + 1;
    
    КонецЕсли;
Пока пытаюсь посчитать количество вхождений каждой скобки в строку
24 fisher
 
23.04.21
12:37
(20) В случае с лобовой проверкой - простейшего вида. А в регулярке может жесть жестяная получиться на уровне исполнения.
25 RomanYS
 
23.04.21
12:37
(22) Реально что ли забацать, что будет ТСу если он решение запросом сдаст)?
26 RomanYS
 
23.04.21
12:38
(23) Ты задачу-то свою читал : "и может содержать произвольное количество круглых скобок"
27 dmt
 
23.04.21
12:40
(0) если это тестовое какое-то, должно прокатить так:
Функция ПроверитьСкобки(Выражение)
    
    колОткрытых = 0;
    
    Для к=1 по СтрДлина(Выражение) Цикл
        Если Сред(Выражение, к, 1) = "(" Тогда
            колОткрытых = колОткрытых + 1;
        ИначеЕсли Сред(Выражение, к, 1) = ")" Тогда
            колОткрытых = колОткрытых - 1;
        КонецЕсли;
        
        Если колОткрытых < 0 Тогда
            Возврат Ложь;
        КонецЕсли;
        
    КонецЦикла;
    
    Возврат колОткрытых = 0;
    
КонецФункции
28 Mikeware
 
23.04.21
12:41
(24) с любой
29 RomanYS
 
23.04.21
12:44
(27) Блин, такую ветку запорол))
30 Garykom
 
гуру
23.04.21
12:46
(21) добавить проверку что в самой середине нет )( или )...(
Как была проверка на пустые ()
31 RomanYS
 
23.04.21
12:47
(30) любитель костылей))) их там будет много на твоем пути? Решение в (27)
32 mikecool
 
23.04.21
12:49
(27) чего ты Сред вычисляешь постоянно?
33 mikecool
 
23.04.21
12:49
+32 и ты тоже возвращаешь неверный результат
34 fisher
 
23.04.21
12:50
(30) Зачем? Пустая подгруппа может считаться корректным выражением.
35 fisher
 
23.04.21
12:51
(33) Для какого кейса?
36 mikecool
 
23.04.21
12:52
(35) из задачи (0) "Функция должна возвращать одну строчку: "правильно" или "неправильно"."
чего вы все булево возвращаете?
37 Mikeware
 
23.04.21
12:53
(36) профдеформация
38 fisher
 
23.04.21
12:54
(36) Обернет в декоратор, делов-то :)
39 vi0
 
23.04.21
12:55
(15) вроде бы что то подобное рассматривалось в книге Фрилда про регулярки
40 vi0
 
23.04.21
12:56
(24) большое вопрос как будет оформлена эта регулярка и как прокомментирована
синтаксисы позволяют делать из многострочными, с отступами итд, т.е. читабельными
41 vi0
 
23.04.21
12:56
*делать их
42 fisher
 
23.04.21
12:59
(40) Речь не только про читабельность. Хотя "читабельность регулярок" - это оксюморон.
Речь про особенности исполнения. Элементарно можно схлопотать недетерменированную производительность.
43 Fragster
 
гуру
23.04.21
13:00
простейшее тестовое задание, а автор его провалил
44 Mikeware
 
23.04.21
13:01
45 Владислав_
startinpro
 
23.04.21
13:02
Ну раз оно такое простейшее, почему тут нет верного решения ...
46 Mikeware
 
23.04.21
13:03
(45) так кто ж тебе его дастЬ? :-)
делай сам
47 Garykom
 
гуру
23.04.21
13:06
(45) Потому что задание тупое и не детализированное

1. Если это арифметическое выражение то банально попробуй его вычислить, если не упало то считаем что скобки правильно расставлены
Если упало то хз конечно (вдруг там деление на 0 было) но считаем что не правильно
По уму надо ошибку проанализировать

2. Или да писать парсер - синтаксический разбор выражения

3. Вариант предполагается авторами: простейший проверка/парсер в меру способностей тестируемого что он сумеет накалякать
48 Владислав_
startinpro
 
23.04.21
13:07
Я понял, всем спасибо
49 timurhv
 
23.04.21
13:10
Обходить все символы, если "(", то счетчик + 1, если ")", то счетчик -1. Если счетчик отрицательный, то ошибка?
Такой вариант правильный?
50 timurhv
 
23.04.21
13:10
(49) ну и в конце дб равен 0
51 Владислав_
startinpro
 
23.04.21
13:18
Я столкнулся с ошибкой при обходе символов в строке, пишу:
Для каждого Буква из ТестоваяСтрока Цикл
.....(условие проверки),
подскажите, как сделать обход по каждому символу в строке
52 Mikeware
 
23.04.21
13:21
(51) сред()
итератора для строки в 1с нет
53 dmt
 
23.04.21
13:22
54 Irbis
 
23.04.21
13:24
А выражение "(·)(·)" считается за ошибку или нет?
55 fisher
 
23.04.21
13:26
(54) С каких это пор сиськи считаются ошибкой?
56 Garykom
 
гуру
23.04.21
13:27
(54) Сисек может быть от 0 до X
57 Mikeware
 
23.04.21
13:27
(55) был определенный период
58 Mikeware
 
23.04.21
13:28
(56) ты про размер или про количество?
59 Mikeware
 
23.04.21
13:29
(56) ну и"до X" они могут быть только в Тайланде...
60 fisher
 
23.04.21
13:32
(59) Некоторые считают, что с хорошими сиськами и X не нужен, а некоторые перестраховываются.
61 Kassern
 
23.04.21
13:33
(52) зачем эти циклы и обходы посимвольные, когда можно:
    КоличествоСкобокВкл=СтрРазделить(Выражение,"(").Количество();
    КоличествоСкобокВыкл=СтрРазделить(Выражение,")").Количество();
    Сообщить(КоличествоСкобокВкл=КоличествоСкобокВыкл);
62 RomanYS
 
23.04.21
13:35
(61)
)(
63 Kassern
 
23.04.21
13:36
(62) точно, порядок же еще...
64 fisher
 
23.04.21
13:36
(62) Тоже вполне достойное выражение.
65 Arbuz
 
23.04.21
13:57
(()о()) устроили.
Простейшая алгоритмическая задача. Решается каждый раз при написании любого мало-мальски рабочего синтаксического разбора и, к тому же, находится место, где именно неправильная скобка. Почему никто про необходимость учёта корректности вложенности скобок не говорит? типа "())(()".
66 Irbis
 
23.04.21
13:59
(65) это уже перетёрли, кури тему внематочнее
67 Arbuz
 
23.04.21
14:01
(66) покажи где
68 Kassern
 
23.04.21
14:02
(67) (61) (62)
69 Irbis
 
23.04.21
14:02
(67) см (27) наприклад
70 Mikeware
 
23.04.21
14:03
(67) в (15), например. даже в (27) решение
71 Irbis
 
23.04.21
14:04
В (27) только пустые скобки останутся правильными.
72 hhhh
 
23.04.21
15:19
(71) чего это? нормально там всё
73 H A D G E H O G s
 
23.04.21
16:09
Пусть этим займется 1С
Попытка
Вычислить(ПроверяемоеВыражение);
Исключение
КонецПопытки

1С все равно сделает это лучше.
74 Kassern
 
23.04.21
16:21
(73) проблема в том, что в тексте может быть все что угодно, а задача проверить только корректность скобочек. Следовательно из поста ТС, выражение "()" должно вернуть правильно, а ")(" - неправильно, если я все правильно понял
75 Garykom
 
гуру
23.04.21
16:39
(74) "(что то есть)" должно вернуть правильно
() как бы не корректно
76 Garykom
 
гуру
23.04.21
16:39
(73) см (3)
77 fisher
 
23.04.21
16:46
(75) Это в 1С некорректно. А в другой среде вполне может быть корректно.
78 Sserj
 
23.04.21
16:57
Функция ПроверитьСкобки(Выражение)
  результат = Неопределено;
  стек = Новый СписокЗначений;
  Для номерСимвола = 1 по СтрДлина(Выражение) Цикл
    токен = Сред(Выражение, номерСимвола, 1);
    Если не токен = ")" и не токен = "(" Тогда
      Продолжить;
    КонецЕсли;
    Если стек.Количество() = 0 Тогда
      Если токен = ")" Тогда
        результат = Ложь;
        Прервать;
      Иначе
        стек.Добавить(токен);
      КонецЕсли;
    ИначеЕсли токен = "(" Тогда
      стек.Добавить(токен);
    ИначеЕсли стек[стек.Количество() - 1].Значение = токен Тогда
      стек.Добавить(токен);
    Иначе
      стек.Удалить(стек.Количество() - 1);
    КонецЕсли;
  КонецЦикла;
  
  Если результат = Неопределено Тогда
    результат = (стек.Количество() = 0);
  КонецЕсли;

  Возврат результат;
КонецФункции
79 fisher
 
23.04.21
17:11
(78) Жесть какая. И чем это лучше (27), кроме того что хуже? Эхо алгоритма Дейкстры нахлобучило? :)
80 acht
 
23.04.21
17:24
(78) > Если не токен = ")" и не токен = "(" Тогда

Офигенный пример к чему приводит выпендреж с использованием "не =" вместо "<>"

Что проще прочитать:
    Если не токен = ")" и не токен = "(" Тогда
или
    Если Токен <> ")" и Токен <> "(" Тогда

?
81 Kassern
 
23.04.21
17:25
(80) я конструкцию НЕ использую обычно с функциями к примеру Если Не РаботаетИнтернет() Тогда
82 Kassern
 
23.04.21
17:26
(80) хотя может это дело привычки восприятия... кому НЕ а кому <>
83 программистище
 
23.04.21
17:26
(80) вкусовщина
84 acht
 
23.04.21
17:26
(81) Ну там еще отрицание в идентификаторах давить надо. У некоторых получаются перлы типа

Если Не ИнтернетНеРаботает() Тогда
85 acht
 
23.04.21
17:27
(83) Ты должен был спеть это и станцевать!
86 Sserj
 
23.04.21
17:37
(79) Тем что (27) не учитывает порядок, он пропустит: )))((( или (()))(
(80) Мне проще прочитать с "не", знак равенства не оставляет в голове каких то других возможных вариантов, а БольшеИлиМеньше всегда цепляет взгляд на подумать а что больши или меньше.
87 Вафель
 
23.04.21
17:39
Это же классическая задача в программировании.
88 Вафель
 
23.04.21
17:41
Сдается что тс и задали такую задачу.
Универ?
89 fisher
 
23.04.21
18:05
(86) Учитывает. Не пропустит.
90 ДедМорроз
 
24.04.21
17:36
В тексте могут быть литералы (читай числа),имена переменных или функций(по условию задачи не понятно).
А также операторы,бинарные и угарные (такие как НЕ или минус).
Просто,построить дерево вычисления,в процессе построения будет понятно,правильное выражение или нет.
91 spectre1978
 
24.04.21
21:22
По классике рекурсией делается. Открытая скобка, читаем выражение до закрытой. Если вновь открытая, то рекурсивный вызов себя же.  Если не встретилась закрывающая, то косяк "неправильно", если везде встретилась, то "правильно".
92 Garykom
 
гуру
24.04.21
21:38
(91) и (10)()(-17) ?
93 fisher
 
26.04.21
12:54
(91) На рекурсию ложится, но тут даже рекурсия не нужна. Рекурсия ведь не бесплатна.
(92) Если нужна еще и проверка корректности выражений внутри скобок - тогда это полный разбор надо делать. Но он тоже несложный. Есть классический алгоритм Дейкстры для преобразования выражений со скобками и приоритетом операций в обратную польскую нотацию (со стеком операций и очередью вывода): https://ru.wikipedia.org/wiki/Алгоритм_сортировочной_станции
Но мне нравится другая его модификация на двух стеках, которая производит вычисления по ходу разбора выражения. Навскидку вроде вот на хабре нашлось: https://habr.com/ru/post/50196/
94 Volodja
 
26.04.21
13:30
(75) Очень даже может быть корректно и в 1С, если в выражении функция
(4*ЧислоПИ())