: "1 - 2 * 3 + 4 * 2 - 1 - 2"
"8/2 + 1/2 * 2/2 - 1"
Leerzeichen werden verwendet, um die Token in dieser einfachen Implementierung zu trennen. Weitere Tests sind in der unten stehenden Quellcode zur Verfügung:
def calc(str):
tokens = str.split(" ")
vals = []
ops = []
i = 0
while i < len(tokens):
t = tokens[i]
if t == "+":
processPlus(ops, vals)
elif t == "*":
ops.append(t)
elif t == "-":
processPlus(ops, vals)
i, t = incrementAndGet(i, t, tokens)
vals.append(float(t) * -1)
elif t == "^":
previousVal = vals.pop()
i, t = incrementAndGet(i, t, tokens)
vals.append(pow(previousVal, float(t)))
elif t == "/":
previousVal = vals.pop()
i, t = incrementAndGet(i, t, tokens)
vals.append(previousVal/float(t))
else:
vals.append(float(t))
i += 1
while len(ops) > 0:
processOp(vals, ops)
return sum(vals)
def incrementAndGet(i, t, tokens):
i += 1
t = tokens[i]
return i, t
def processPlus(ops, vals):
if len(ops) > 0:
processOp(vals, ops)
ops.append("+")
def processOp(vals, ops):
op = ops.pop()
if op == "+":
vals.append(vals.pop() + vals.pop())
elif op == "*":
vals.append(vals.pop() * vals.pop())
# Test section
def check(expr, expected):
res = calc(expr)
print(res)
assert res == expected
check("8/2/2/2", 1.0)
check("8/2 + 1/2/2", 4.25)
check("8/2 + 1/2 * 2/2", 4.5)
check("8/2 + 1/2 * 2/2 - 1", 3.5)
check("1 + 2", 3)
check("1 - 2", -1)
check("2 * 3", 6)
check("1 + 2 * 2", 5)
check("2 * 3 + 2", 8)
check("1 * 2 + 2 * 3", 8)
check("1 * 2 + 2 * 3 + 1", 9)
check("1 * 2 + 2 * 3 + 1 + 2", 11)
check("1 * 2 + 2 * 3 + 1 + 2 * 2", 13)
check("1 - 2 * 3 + 4 * 2 - 1 - 2", 0.0)
check("1 - 2 * 3 + 4 * 2 - 1 - 2 * 2", -2.0)
check("1 - 2 * 3 + 4 * 2 - 1 - 2 * 2 - 3", -5.0)
check("2^2", 4.0)
check("2 + 3^2", 11.0)
check("2 + 3^2 - 1", 10.0)
check("2 + 3^2 - 1 * 3", 8.0)