|
#!/usr/bin/env python
#coding=utf-8
#实现加减乘除-无优先级,从左至右计算
def split_str(str):
L = []
s_index = 0 #上次切割的索引
i = 0 #遍历时当前的索引
#print str
for s in str:
if s in '+-*/': #遇到运算符开始执行切割
L.append(str[s_index:i]) #写入list
# print "str[s_index:i]: ",str[s_index:i]
s_index = i #上次切割索引前移
# print "s_index :", s_index
i += 1 # 非运算符索引前移
# print 'i: ',i
L.append(str[s_index:])#切割后最后一部分写入list
init_value = L[0] #list第一个值无需计算,设为初始值
for num in range(1,len(L)):
init_value = calculate_list(init_value,L[num]) #计算结果赋值给初始值,即左操作数
return init_value
def calculate_list(a,b):
return operate_map[b[0]](int(a),int(b[1:]))
#定义词典 + - * / 符号为key,value为运算结果
operate_map = {
'+' : lambda x,y : x+y,
'-' : lambda x,y : x-y,
'*' : lambda x,y : x*y,
'/' : lambda x,y : x/y
}
if __name__ == '__main__':
cal_str = "8/2+10+2*3-14"
cal_list = split_str(cal_str)
print cal_list
以上为$ cat calculate1.py
利用上面的的规则实现优先级:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| #!/usr/bin/env python
#coding=utf-8
from calculate1 import *
#实现加减乘除 -- 有优先级 ,先 * / 后 + -
def _split_str(str):
L = []
s_index = 0 #上次切割的索引
i = 0 #遍历时当前的索引
print str
for s in str:
if s in '-+': #遇到+-运算符开始执行切割
L.append(str[s_index:i]) #写入list
L.append(s) #写入list
s_index = i+1 #上次切割索引前移
i += 1 # 非运算符索引前移
L.append(str[s_index:])#切割后最后一部分写入list
return L
#cal_str = "12+11/13*1-5*9"
cal_str = raw_input("Enter an arithmetic express:")
cal_list = _split_str(cal_str)
#['12', '+', '11/13*1', '-', '5*9']
s=''
for i in cal_list:
if "*" in i or '/' in i:
s=s+str(split_str(i))
else:
s=s+str(i)
print split_str(s)
|
另外在Stackoverflow上看到的后缀四则运算的代码,记录下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
| #The question I'm having problem on is calculating the postfix form expressions: for example, (1, 2, '+', 3, '*').
#http://stackoverflow.com/questio ... n/22585579#22585579
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
is_str = lambda s: isinstance(s, basestring)
inp = raw_input
else:
# Python 3.x
is_str = lambda s: isinstance(s, str)
inp = input
class Stack(list):
def pop_n(self, n):
"""
Pop n items off stack, return as list
"""
assert n >= 0, "Bad value {}: n cannot be negative".format(n)
if n == 0:
return []
elif n <= len(self):
res = self[-n:]
del self[-n:]
print "Stack pop_n res:", res
return res
else:
raise ValueError("cannot pop {} items, only {} in stack".format(n, len(self)))
def push_n(self, n, items):
"""
Push n items onto stack
"""
assert n == len(items), "Expected {} items, received {}".format(n, len(items))
self.extend(items)
print "Stack push_n self: ", self
class Op:
def __init__(self, num_in, num_out, fn):
"""
A postfix operator
num_in: int
num_out: int
fn: accept num_in positional arguments,
perform operation,
return list containing num_out values
"""
assert num_in >= 0, "Operator cannot have negative number of arguments"
self.num_in = num_in
assert num_out >= 0, "Operator cannot return negative number of results"
self.num_out = num_out
self.fn = fn
def __call__(self, stack):
"""
Run operator against stack (in-place)
"""
args = stack.pop_n(self.num_in) # pop num_in arguments
print "Op args: ",args
res = self.fn(*args) # pass to function, get results
print "Op res: ",res
stack.push_n(self.num_out, res) # push num_out values back
print "Op stack", stack
ops = {
'*': Op(2, 1, lambda a,b: [a*b]), # multiplication
'/': Op(2, 1, lambda a,b: [a//b]), # integer division
'+': Op(2, 1, lambda a,b: [a+b]), # addition
'-': Op(2, 1, lambda a,b: [a-b]), # subtraction
'/%': Op(2, 2, lambda a,b: [a//b, a%b]) # divmod (example of 2-output op)
}
def postfix_eval(tokens):
"""
Evaluate a series of tokens as a postfix expression;
return the resulting stack
"""
if is_str(tokens):
# if tokens is a string, treat it as a space-separated list of tokens
tokens = tokens.split()
stack = Stack()
for token in tokens:
try:
# Convert to int and push on stack
stack.append(int(token))
print "postfix_eval stack :", stack
except ValueError:
try:
# Not an int - must be an operator
# Get the appropriate operator and run it against the stack
op = ops[token]
print "postfix_eval op:", op
#op(stack) # runs Op.__call__(op, stack)
print "token:",token
print "postfix_eval op(stack)", op(stack)
except KeyError:
# Not a valid operator either
raise ValueError("unknown operator {}".format(token))
return stack
def main():
while True:
expr = inp('\nEnter a postfix expression (or nothing to quit): ').strip()
if expr:
try:
print(" => {}".format(postfix_eval(expr)))
except ValueError as error:
print("Your expression caused an error: {}".format(error))
else:
break
if __name__=="__main__":
main()
|
|
|