我正在写一个python程序来计算公式。我读入了一个字符串列表,其中包含值、运算符和函数。
下面显示的代码接收一个字符串,例如:
['not', 1.0, 2.0, '=', 'power', 2.0, 3.0, '+']上面的代码是数学问题的后缀版本: power(2,3)+not(2=1)程序应该首先计算not(2=1),结果是1,然后计算power(2,3)给9,然后计算8+0,结果是8。
到目前为止,我计算答案的代码
stack = []
def calculate(inputs):
if (inputs[0] == "sum"):
inputs.remove("sum")
for a in inputs:
if (a) == "not":
inputs.remove(a)
op1, op2 = inputs[0], inputs[1]
inputs.remove(op1)
inputs.remove(op2)
if op1 != op2:
stack.append('0')
else:
stack.append('1')
continue
if (a) == 'power':
inputs.remove(a)
continue
if type(a) is float:
stack.append(a)
continue
op1, op2 = stack.pop(), stack.pop()
#if a == 'power':
if a == '+':
stack.append(op2 + op1)
elif a == '-':
stack.append(op1 - op2)
elif a == '*':
stack.append(op2 * op1)
elif a == '/':
stack.append(op1 / op2)
elif a == '=':
if op1 != op2:
stack.append('0')
else:
stack.append('1')
if (len(stack) > 1):
lenStack = len(stack)-1
for x in range(0, lenStack):
stack.append('+')
stack.append(_calcSum(stack))
return stack.pop()
def _calcSum(stack):
newStack = []
for a in stack:
if type(a) is float:
newStack.append(a)
continue
op1, op2 = newStack.pop(), newStack.pop()
if a == '+':
newStack.append(op2 + op1)
elif a == '-':
newStack.append(op1 - op2)
elif a == '*':
newStack.append(op2 * op1)
elif a == '/':
newStack.append(op1 / op2)
return newStack.pop()但是,我在使用NOT和POWER语句时遇到了问题;我不知道如何自动检查这些语句。有没有人可以给我指出正确的方向,或者帮助我编写代码?当我尝试检查“power”时,它只是跳过我的其余代码,并尝试打印堆栈-它是空的,从而导致错误。
发布于 2015-01-09 05:02:29
我认为下面的代码可能是您想要的:
import math
test_input = ['2', '1', '=', 'not', '2', '3', 'power', '+']
def calculate(input):
newStack = []
for a in input:
print newStack
if a == '+':
op1, op2 = newStack.pop(), newStack.pop()
newStack.append(op2 + op1)
elif a == '-':
op1, op2 = newStack.pop(), newStack.pop()
newStack.append(op1 - op2)
elif a == '*':
op1, op2 = newStack.pop(), newStack.pop()
newStack.append(op2 * op1)
elif a == '/':
op1, op2 = newStack.pop(), newStack.pop()
newStack.append(op1 / op2)
elif a == '=':
op1, op2 = newStack.pop(), newStack.pop()
if op1 == op2:
newStack.append(1)
else:
newStack.append(0)
elif a == 'not':
op = newStack.pop()
if op > 0:
newStack.append(0)
else:
newStack.append(1)
elif a == 'power':
op1, op2 = newStack.pop(), newStack.pop()
newStack.append(math.pow(op1, op2))
else:
newStack.append(float(a))
return newStack.pop()正如PeterE在他的评论中指出的,你的后缀代码是错误的。我假设您想要的后缀代码可能是2 1 = not 2 3 power +。还要注意的是,最终值应该是9+1 = 10而不是8+0 = 8。
维基百科有一个很好的后缀代码页面:http://en.wikipedia.org/wiki/Reverse_Polish_notation。
在python代码中,一个函数实际上应该足以将所有需要的东西推送和弹出到堆栈上。要实现基本的实现,您可以简单地检查所有不同的运算符情况,并执行任何需要的操作。如果提供的运算符都不与当前元素匹配,则可以假定该元素是一个数值,并简单地推送解析后的浮点值。
请注意,这是一个非常快速和肮脏的实现,但它可能会引导您走上正确的道路。
发布于 2015-01-09 18:14:52
基于IXI的答案,您可以通过使用函数式编程显著降低复杂性和代码量:创建从符号到要执行的操作的映射,然后在该映射中查找输入中的符号。这样做,您将看到power和not一点也不特殊,并且可以很容易地添加额外的一元和二元运算符。您甚至可以扩展它以支持三元运算符,例如... if ... else ... (尽管您必须以后缀的形式编写它们)。
BIN_OP = {"+": lambda x, y: x + y,
"-": lambda x, y: x - y,
"*": lambda x, y: x * y,
"/": lambda x, y: x / y,
"power": lambda x, y: x**y,
"=": lambda x, y: int(x == y)}
UN_OP = {"not": lambda x: int(not x)}
def calculate(tokens):
stack = []
for token in tokens:
if token in BIN_OP:
op1, op2 = stack.pop(), stack.pop()
operation = BIN_OP[token]
stack.append(operation(op1, op2))
elif token in UN_OP:
op1 = stack.pop()
operation = UN_OP[token]
stack.append(operation(op1))
else:
stack.append(float(token))
return stack.pop()示例:
>>> calculate(['2', '1', '=', 'not', '2', '3', 'power', '+'])
10.0发布于 2015-01-09 20:33:44
关于冗余精化的主题,这里是tobias_k的解决方案的一个变体,它针对更少的特殊情况进行了重构:
from operator import add, sub, mul, truediv, pow, eq, not_
ops = {"+": add, "-": sub, "*": mul, "/": truediv,
"power": pow, "=": eq, "not": not_}
# Mark how many inputs are needed
ops = {k:(1 if f is not_ else 2, f) for (k,f) in ops.items()}
def calculate(tokens):
stack = []
for token in tokens:
try:
args,func = ops[token]
stack[-args:] = [func(*stack[-args:])]
except KeyError:
stack.append(float(token))
return float(stack[-1])示例:
>>> calculate("2 1 = not 2 3 power +".split())
9.0
>>> calculate("2 1 = not".split())
1.0
>>> calculate("2 3 power".split())
8.0是的,我使用的是Python的bool类型是int的子类型,所以True实际上是1。生成9还是10的区别仅仅来自于幂参数的顺序(2**3==8或3**2==9)。
问题的根源仍然是您的原始输入表达式不是有效的后缀表示法,这使得计算顺序清晰,因此运算符优先是多余的。如果not出现在它的参数之前,你怎么知道什么时候评估它?not(1)、not(1==2)和not((1==2)+(3**2)看起来都像是可能的解释,对power也不好。
https://stackoverflow.com/questions/27848840
复制相似问题