|
Как проверить корректность расстановки скобок в выражении? | ☑ | ||
---|---|---|---|---|
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*ЧислоПИ()) |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |