设为首页 收藏本站
查看: 1168|回复: 0

[经验分享] python 实现四则运算 无优先级 VS 有优先级

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-1-28 08:29:55 | 显示全部楼层 |阅读模式
#!/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()



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-41573-1-1.html 上篇帖子: python在rest接口测试中的应用 下篇帖子: 使用python编写ssh工具 python 优先级
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表