Уведомления

Группа в Telegram: @pythonsu

#1 Март 12, 2014 19:12:12

Zubr
Зарегистрирован: 2013-06-25
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Появилась задача, которую ну никак не получается решить своими силами.

Задана строка, содержащая арифметическое выражение. В записи допускаются цифры, символы ‘+’, ‘-‘, ‘*’, ‘/’, ‘.’ и круглые скобки. Вычислить выражение. При вычислении выражения следует учитывать порядок выполнения арифметических действий. Если выражение вычислить невозможно – выдать сообщение об ошибке.
Исходные данные
В единственной строке находится арифметическое выражение. В выражении могут использоваться символы 0-9, +, -, *, / и пробел.
Результат
В единственной строке вывода вывести значение выражения или «ERROR» если выражение содержит ошибки или не может быть вычислено.
Пример
Исходные данные
2+2*2-(2/2+2)
Результат
3
В алгоритме указано, что нужно завести 2 стека. Один для операндов, а второй для операций (в котором будет храниться информация об арифметических действиях, производимых при вычислении). Но я не могу придумать как выполнить проверку строки на наличие int или float, чтобы потом занести это в стек операндов.

Офлайн

#2 Март 12, 2014 19:49:58

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

 s = '2+2*2-(2/2+2)'
eval(s)
>>> 3

Офлайн

#3 Март 12, 2014 19:56:54

Zubr
Зарегистрирован: 2013-06-25
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Singularity
Спасибо за ответ. На с++ все намного страшнее, и в помощь нам дали вот такой алгоритм:
В алгоритме будет использоваться два стека: стек операций (в котором будет храниться информация об арифметических действиях, производимых при вычислении) и стек операндов (в котором будет храниться информация о числах, над которыми производятся действия). Как следует из назначения стека операндов, его элементы должны быть такого типа, который может хранить действительные числа (в записи выражения допустима десятичная точка). Стек операций удобно сделать символьным.
Алгоритм вычисления выражения строится следующим образом. Посимвольно просматривается исходная строка. Если текущий элемент строки – цифра, то выделяется число, в запись которого она входит, и заносится в стек операндов. Если встречается символ открытой скобки или операции умножения или деления, то они заносятся в стек операций. Если встречаются операции сложения, вычитания или закрытой скобки, то запускается процедура вычисления уже разобранной и находящейся в стеках части выражения. После этого операции сложения и вычитания заносятся в стек операций, а закрытая скобка удаляется вместе с соответствующей ей открытой. Если в стеке операций соответствующая открытая скобка отсутствует после частичного вычисления выражения, то в записи выражения допущена ошибка и выводится соответствующее сообщение. При достижении конца строки вычисляется оставшаяся в стеках разобранная часть выражения.
Вычисление частично разобранного выражения происходит следующим образом. До тех пор, пока в стеке операций находятся операции и очередная из них - не открытая скобка, со стека операндов снимается два числа (первое число - это второй операнд, а второе из снимаемых чисел - первый, т.к. в стеке порядок следования элементов меняется на противоположный) и над ними производится соответствующее действие. Результат вычисления заносится в стек операндов и в дальнейшем используется как операнд при вычислении следующих операций. Следует обратить внимание на отслеживание деления на 0, т.к. это действие считается недопустимым и должно приводить в выдаче сообщения об ошибке. Вычисления проводятся до первой открытой скобки в стеке операций по причине того, что действия в скобках выполняются до всех остальных действий. Таким образом, пока не будет получено число, равное результату выполнения действий в скобках, выполнение остальных операций временно откладывается (они запоминаются в стеке).
После достижения конца строки необходимо снять результат вычислений со стека операндов и проверить, не осталось ли значений в стеках. Если стеки не пусты, то в выражении были допущены ошибки, и необходимо вывести соответствующее сообщение.

Офлайн

#4 Март 12, 2014 20:08:20

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

stack = []
stack.append(something)
stack.pop()
мне лень это делать. Погугли наверно кто-то уже такое делал

Отредактировано Singularity (Март 12, 2014 20:08:34)

Офлайн

#5 Март 12, 2014 20:13:35

Zubr
Зарегистрирован: 2013-06-25
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Singularity
Как работает стек - я понимаю.
EXPRESSION = input(“Введите выражение”)
Вот я не пойму как в строке EXPRESION проверить числа там или нет, для добавления в стек.

Офлайн

#6 Март 12, 2014 20:42:41

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Zubr
посмотреть есть ли там что-то кроме цифр и точки

Офлайн

#7 Март 12, 2014 20:46:01

Zubr
Зарегистрирован: 2013-06-25
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Спасибо за наводки, буду думать.

Офлайн

#8 Март 12, 2014 22:21:17

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Zubr
Вот я не пойму как в строке EXPRESION проверить числа там или нет
можешь разделить на лексемы (по пробелу) через .split()
потом брать по лексеме и проверять её на пригодность (сделай функцию)
надо учесть, что числа могуть быть дробными

Singularity
мне лень это делать. Погугли наверно кто-то уже такое делал
это развивает базовые навыки по обработке грамматик
у меня в книжке, по которой занимаюсь, есть пример аналогичный, но там через рекурсию сделано, и есть вес у операций

для разработки своего транслятора чего-нибудь во что-нибудь очень пригодится



Офлайн

#9 Март 13, 2014 09:24:26

Zubr
Зарегистрирован: 2013-06-25
Сообщения: 13
Репутация: +  1  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

py.user.next
А скажите название книги?
Появилась еще идея с обратной польской записью. Но пока не знаю как ее реализовать.

Офлайн

#10 Март 13, 2014 11:31:09

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10010
Репутация: +  857  -
Профиль   Отправить e-mail  

Вычисление арифметического выражения

Zubr
А скажите название книги?
картинка


там компиляция арифметической формулы в программу для стекового калькулятора

Zubr
Появилась еще идея с обратной польской записью.
она там не нужна
алгоритм однопроходный



Отредактировано py.user.next (Март 13, 2014 11:34:44)

Прикреплённый файлы:
attachment progmat.jpg (98,6 KБ)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version