彩世界平台-彩世界时时app-彩世界开奖app苹果下载

热门关键词: 彩世界平台,彩世界时时app,彩世界开奖app苹果下载

您的位置:彩世界平台 > 彩世界平台 > 使用栈Stack对整数数值的运算表达式字符串进行运

使用栈Stack对整数数值的运算表达式字符串进行运

发布时间:2019-09-04 00:31编辑:彩世界平台浏览(157)

    使用Python运算一个字符串表达式

     

         这里如果对于形如字符串“((6+((7+8)-9)*9+8/2)-3)/2”的运算表达式进行运算。接触过此类的同学知道这种存在着运算符优先级的表达式,不能直接从左到右进行运算,我们使用OperandStack操作数栈和OperatorStack操作符栈,对操作符进行比较,确定优先级后,取出操作数进行运算。

    概述:

    如何运行一个表达式,例如:12+23*4/2这个我想大家都很了解。不过,如果这个表达式是一个字符串呢?或是这样来描述,一个表达式被写成了一个字符串,我们又应该如何去运行并求得值呢?你是否会想,如果我们能够拿到12, 23, 4, 2以及中间的运算符,那就是真的太好了。而事实上,我们也正是在朝着这个方向去努力。如果你学过算法或是数据结构,那我想这个小问题便不会阻止你前进了。

        算法思想如下:

    思路分析:

    如概述所说,如果我们能拿到字符串表达式中中各个我们肉眼能够识别的“元素”,就算我们迈过了第一步。什么!才第一步?是的,这才是第一步。那第二步是什么?
    没错,第二步就是运算。运算的过程会有一个难题,这个难题就是操作符的优先级问题,就拿上面的表达式来说,我们需要先进行23*4的运算,而不是12+23的运算。我们要做的就是让计算机按照我们认知中的优先来做运算。比较笨的方法就是依次遍历两遍表达式(事实上在后期的运算中,我们遍历的是一个列表)。第一遍先做乘除、第二遍再做加减。

    1.首先确定操作的符的优先级,*、/大于+、-,(大于*、/,*、/或者+、-一起时,排在前面的运算符优先,)的优先级最小,且)与(相遇时抵消

    元素分离:

    对于这一步操作在Python中进行的确很省事,因为我们可爱的Python可以在列表中存储不同类型的对象。这就有点像C中的结构体和Java中的类。我们首先得到的是一个个的字符,再对这些字符进行遍历和分类(是数字还是操作符)。

     

     

    # split expression
    def mixed_operation (exp):
        exp_list = list(exp)
        temp = ''
        behavor_list = []
        i = 0
        length = len(exp_list)
        for item in exp_list:
            if is_operation(item):
                behavor_list.append(int(temp))
                behavor_list.append(item)
                temp = ''
            else:
                temp += item
    
            if i == length - 1:
                behavor_list.append(int(temp))
                break;
    
            i += 1
    
        return behavor_list
    

     

    2.从左到右遍历字符串,每次遍历一个字符,设置数字临时存储变量OperandTemp

    逻辑运算:

    这个函数有一些特别,对于有编程经验的朋友可能已经不陌生。对,就是递归!对于一个coder,递归是必须掌握的,就让我们一起在合适的时候把递归搞起吧。这里写递归的原因就是我们的表达式中每一种运算符不可能只有一种。我们要一直这样遍历下去。这时可能你已经感觉到了,遍历的话,为什么不用for?是的,在我的代码里也有for的循环代码,不过这里的for可没有想像中那么好用,不信你可以试试看。

     

     

    # Calculation op1 and op2('*' and '/' or '+' and '-')
    def cal_op1_op2(exp_list, op1, op2):
        if len(exp_list) == 1:
            return exp_list
    
        i = 0
        has_op = False
        for i in range(2, len(exp_list), 2):
            a = exp_list[i - 2]
            o = exp_list[i - 1]
            b = exp_list[i]
            if o == op1 or o == op2:
                has_op = True
                exp_list[i - 2] = get_aob(a, o, b)
                del exp_list[i]
                del exp_list[i - 1]
                break
    
        if has_op == False:
            return exp_list
    
        return cal_op1_op2(exp_list, op1, op2)
    

     

    ①当遇到操作符时, 如果OperandTemp有数值,把数字压入到OperandStack中

    特别说明:

    当然对于这个程序来说,并不是那么健壮。因为我们这些逻辑的前提是我们得到了一个正常的表达式,且不包含括号。所谓正常表达式,就是不会出现少数字或是少操作符或是输入了非'+'、'-'、'*'、'/'、[0-9]的字符或是字符集。我们的程序默认了一个理想的运行环境,因为只是说明代码的思路。

    ②循环OperatorStack,直到OperatorStack没值为止,然后比较这个操作符和OperatorStack顶部的运算符进行比较,如果此操作符运算优先级高,将此运算符压入栈,退出循环;如果此操作符运算优先级低,则将OperatorStack栈顶的运算符取出ope1,从OperandStack中取出顶部的两个数值a1(先出栈)和a2,注意首先出栈的做第二个操作数,则进行

    附完整代码:

     

     

    #!/usr/bin/env python
    
    'expression_cal.py -- cal the expression that you give to me'
    
    # judgment a char is a operation or not
    def is_operation(oper):
        if oper == '+' or oper == '-' or oper == '*' or oper == '/':
            return True
        else:
            return False
    
    # split expression
    def mixed_operation (exp):
        exp_list = list(exp)
        temp = ''
        behavor_list = []
        i = 0
        length = len(exp_list)
        for item in exp_list:
            if is_operation(item):
                behavor_list.append(int(temp))
                behavor_list.append(item)
                temp = ''
            else:
                temp += item
    
            if i == length - 1:
                behavor_list.append(int(temp))
                break;
    
            i += 1
    
        return behavor_list
    
    # cal a o b
    def get_aob(a, o, b):
        if o == '+':
            return a + b
        elif o == '-':
            return a - b
        elif o == '*':
            return a * b
        elif o == '/':
            return a / b
    
    # Calculation op1 and op2('*' and '/' or '+' and '-')
    def cal_op1_op2(exp_list, op1, op2):
        if len(exp_list) == 1:
            return exp_list
    
        i = 0
        has_op = False
        for i in range(2, len(exp_list), 2):
            a = exp_list[i - 2]
            o = exp_list[i - 1]
            b = exp_list[i]
            if o == op1 or o == op2:
                has_op = True
                exp_list[i - 2] = get_aob(a, o, b)
                del exp_list[i]
                del exp_list[i - 1]
                break
    
        if has_op == False:
            return exp_list
    
        return cal_op1_op2(exp_list, op1, op2)
    
    # cal exp
    def cal_exp(exp_list):
        exp_list = cal_op1_op2(exp_list, '*', '/')
        exp_list = cal_op1_op2(exp_list, '+', '-')
    
        return exp_list[0]
    
    while True:
        expre = raw_input('Enter your expression(0 to end):n')
        if expre == '0':
            break
    
        result = mixed_operation(expre)
        print 'list result = ',
        print result
        print cal_exp(result)
    
    print 'END'
    

     

    概述: 如何运行一个表达式,例如:12+23*4/2这个我想大家都很了解。不过,如果这个表达式是一个字符串...

     a2 ope1 a1;求得结果压人OperandStack中;如果此操作符是)遇到(时,将OperatorStack栈中的(消除

    ③循环到最后会剩余2中情况,即OperatorStack中剩1个运算符,剩余两个运算符,且最后一个运算符优先级高,则读取最后一个数字和OperandStack顶的数字进行操作运算,求得结果,再运算。

    以字符串“((6+((7+8)-9)*9+8/2)-3)/2”为例,算法的运算过程是,先将((压入OperatorStack变为【((】,将6压入OperandStack【6】,到+,由于(不参与运算,则将+压入

    本文由彩世界平台发布于彩世界平台,转载请注明出处:使用栈Stack对整数数值的运算表达式字符串进行运

    关键词: