python语言基于栈实现计算器

来源:互联网 发布:火车头数据采集器 编辑:程序博客网 时间:2024/06/06 03:50

汉语版:

这个小程序是基于栈实现的计算器。用python很好实现,python列表的概念和栈有很大的相同之处。所以,我们并不需要实现stack这个类。目前项目是托管在

https://gitee.com/tostronger/data_structure。

项目的整体是一个基于Django框架的web显示。至于如何安装和部署Django项目,网上都有大量的教程。我这里就不再讲解了。

E-version:

this program was implemented by Python, the main data structure is Stack, i use python for that in python there are a lot of commons between list and stack, which you can append or pop a value on the end. so we need not implement STACK class. Now this program was gited on oschina. you can download form this website. when you run this program ,you can access it by the url 127.0.0.1/;because this is a Django project and i won`t told you how prepare Django. Good lucky!

1.接收请求参数,经过计算后返回值,通过模板将返回信息,写入到网页。

I.get the post request param, match the URL and action then return the result

def getresult(request):    ctx = {}    if request.POST:        str_input = request.POST['iWord']        ctx['original'] = str_input        ctx['rlt'] = stacks.get_stack_value(str_input)    return render(request, "home.html", ctx)
2.下面这个函数是获取参数的返回值

II.return the final result

def get_stack_value(input_str):    # 存放操作数    operator = []    # 存放操作符    operate = []    # 存放顶部操作符    top = ''    # 存放flag,flag为真,不添加当前字符    flag = False    # 临时操作数    temp_str = ''    # 预处理:basic_work(input_str)    input_str = tool.basic_work(input_str)    for index in range(len(input_str)):        # 遇到操作符,进行下面操作        if len(operate) >= 1:            top = operate[len(operate) - 1]        else:            top = ''        # 测试专用一:打印每次操作数和操作符        # print('top',operator)        # print('top',operate)        if input_str[index] == '+':            flag,temp_str = tool.set_operator_value(temp_str,operator)            tool.simple_caculate('+', top, 'out', input_str[index], operate, operator)        if input_str[index] == '-':            flag, temp_str = tool.set_operator_value(temp_str, operator)            tool.simple_caculate('-', top, 'out', input_str[index], operate, operator)        if input_str[index] == '*':            flag, temp_str = tool.set_operator_value(temp_str, operator)            tool.simple_caculate('*', top, 'out', input_str[index], operate, operator)        if input_str[index] == '/':            flag, temp_str = tool.set_operator_value(temp_str, operator)            tool.simple_caculate('/', top, 'out', input_str[index], operate, operator)        if input_str[index] == '%':            flag, temp_str = tool.set_operator_value(temp_str, operator)            tool.simple_caculate('%', top, 'out', input_str[index], operate, operator)        if input_str[index] == '^':            flag, temp_str = tool.set_operator_value(temp_str, operator)            tool.simple_caculate('^', top, 'out', input_str[index], operate, operator)        if input_str[index] == '&':            flag, temp_str = tool.set_operator_value(temp_str, operator)            tool.simple_caculate('&', top, 'out', input_str[index], operate, operator)        if input_str[index] == '.':            flag = False        if input_str[index] == '(':            operate.append(input_str[index])            flag = True        if input_str[index] == ')':            flag, temp_str = tool.set_operator_value(temp_str, operator)            if tool.compare_operation(')', top, 'out') == '<':                if len(operator) >= 2:                    while operate[len(operate) - 1] == '(':                        operate.pop()                    operator.append(tool.compute_result(operator.pop(), operator.pop(), operate.pop()))                # 测试专用二:调试带括号的问题                # print(operator)                # print(operate)                if len(operate) >= 1 and operate[len(operate) - 1] == '(':                    operate.pop()                else:                    if len(operator) >= 2 :                        operator.append(tool.compute_result(operator.pop(), operator.pop(), operate.pop()))                        operate.pop()        # 遇到数字非法,直接退出;否则,组成临时字符        if (input_str[index] < '0' or input_str[index] > '9') and tool.not_operate(input_str[index]):            input_str = 'error in the\t'+str(index+1) + '\tcharacter!\t' + input_str + '->' + input_str[index]            return input_str        elif input_str[index] == ' ':            continue        else:            if flag:                flag = False            else:                temp_str += input_str[index]        # 遇到‘=’且为最后一个字符,返回结果        if input_str[index] == '=' and index == len(input_str)-1:            length = len(operate)            if length >= 1:                operate.pop()            else:                pass            while len(operate) > 0:                if len(operator) >= 2:                    operator.append(tool.compute_result(operator.pop(), operator.pop(), operate.pop()))                else:                    operate.pop()    return str(operator)
3.这里没有特别需要说明的,函数进口是定义了操作数栈和操作符栈,然后进行基本的字符处理

III.basic dealings for the raw Strings

# 文本预处理def basic_work(input_str):    # 适应操作符连续输入    for index in range(len(input_str)-1):        if is_operator(input_str[index]) and is_operator(input_str[index+1]):            input_str = 'error in statement, duplicate operator :'+str(input_str[index])            return input_str    # 适应首字符存在符号可能性    if input_str[0] == '-':        input_str = '0'+input_str    length = len(input_str)    # 适应用户不输入等号    if input_str[length-1] == '=':        input_str = input_str[0:length-1]        input_str += '+0='    else:        input_str += '+0='    # 适应括号非对称输入    if input_str.count('(') != input_str.count(')'):        input_str = 'error in brackets! it was off-balance'    return input_str
4.执行栈算法,先比较优先级,代码如下

IV.compare the parity among operators

# 比较运算符优先级def compare_operation(operate_one, operate_two, stack_type):    if operate_one == ')' and operate_two == '(':        return '<'    if operate_two == '' or operate_two == '(':        return '>'    if stack_type == 'out':        if '+' == operate_one:            if '(' == operate_two:                return '>'            else:                return '<'        if '-' == operate_one:            if '(' == operate_two:                return '>'            else:                return '<'        if '*' == operate_one:            if operate_two == '+' or operate_two == '-'or operate_two == '=':                return '>'            else:                return '<'        if '/' == operate_one:            if operate_two == '+' or operate_two == '-'or operate_two == '=':                return '>'            else:                return '<'        if '%' == operate_one:            if operate_two == '+' or operate_two == '-' or operate_two == '=':                return '>'            else:                return '<'        if '^' == operate_one:            if operate_two == '+' or operate_two == '-' or operate_two == '=' \                    or operate_two == '*' or operate_two == '%' or operate_two == '/':                return '>'            else:                return '<'        if '&' == operate_one:            if operate_two == '+' or operate_two == '-' or operate_two == '=' \                    or operate_two == '*' or operate_two == '%' or operate_two == '/':                return '>'            else:                return '<'        if ')' == operate_one:            if operate_two == '=':                return '>'            else:                return '<'

5.根据优先级,进行运算

V.STACK operation ,push and pop then caculate

# 出栈,压栈运算def simple_caculate(operate_type, top, temp, input_index, operate=[], operator=[]):    if compare_operation(operate_type, top, temp) == '>':        operate.append(input_index)    if compare_operation(operate_type, top, temp) == '<':        operator.append(compute_result(operator.pop(), operator.pop(), operate.pop()))        operate.append(input_index)# 临时字符运算def set_operator_value(temp_str, operator=[]):    if temp_str == '':        pass    else:        if temp_str.count('.') > 1:            operator.append(str(math.inf))        else:            operator.append(temp_str)        temp_str = ''    return True,temp_str
6.遇到非法字符要退出,所以有非法字符检测

VI.check the vaild input

# 非法字符检测器def not_operate(character):    if character != '+' and character != '-' and character != '*' and character != '/' and character != '^' \            and character != '(' and character != ')' and character != '&' and character != '=' \            and character != '%' and character != '.' and character !=' ':        return True    else:        return False
7.数字过滤器

VII.filter the numbers

# 是否为数字判断def is_operator(character):    if character == '+' or character == '-' or character == '*' or character == '/' or character == '^' \            or character == '&' or character == '='or character == '%' or character == '.':        return True    else:        return False
8.对两个数进行计算

VIII.caculate two number

# 计算数值结果def compute_result(number_one, number_two, operate):    if number_one == '':        number_one = '0'    if number_two == '':        number_two == '0'    param_one = float(number_one)    param_two = float(number_two)    if operate == '+':        return param_two + param_one    if operate == '-':        return param_two - param_one    if operate == '*':        return param_two * param_one    if operate == '/':        if param_one == 0:            return math.inf        return param_two / param_one    if operate == '%':        return param_two % param_one    if operate == '^':        if param_two < 0:            if param_one > 0 and param_one % 2 == 1:                return param_two ** (1/param_one)            elif param_one < 0 and param_one % 2 == 1:                return 1/(param_two ** (1/param_one))            else:                return math.inf        if param_two > 0:            if param_one > 0:                return param_two ** (1/param_one)            elif param_one < 0:                return 1/(param_two ** (1/param_one))            else:                return math.inf    if operate == '&':        return param_two ** param_one

这样就实现了程序。

then we get the test page.