简易计算器-leetcode

今天,开始在leetcode上面开始做题,第一个题目是:

Implement a basic calculator to evaluate a simple expression string.

The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.

You may assume that the given expression is always valid.

Some examples:

  "3+2*2" = 7
  " 3/2 " = 1
  " 3+5 / 2 " = 5
主要思想,先将中缀表达式利用“栈”和“队列”,转换为后缀表达式,其实难点也主要在这里,再计算后缀表达式的值。

首先构造“栈”:

 stack.py

class Stack():
    def __init__(self, size):
        self.size = size
        self.top = -1
        self.stack = []

    def push(self, ele):
        if self.isfull():
            raise Exception("out of range")
        else:
            self.stack.append(ele)
            self.top += 1

    def isfull(self):
        if self.top == self.size - 1:
            return True
        else:
            return False

    def pop(self):
        if self.isEmpty():
            raise Exception("no element")
        else:
            self.top -= 1
            return self.stack.pop()

    def isEmpty(self):
        if self.top == -1:
            return True
        else:
            return False

    def returnFristEle(self):
        return self.stack[self.top]

    def returnStack(self):
        return self.stack

if __name__ == '__main__':
    s = Stack(1)

    for i in xrange(3):
        s.push(i)
    print s.stack, s.top


 接下来,需要构造“队列”:

__author__ = 'Administrator'


class Queue():
    def __init__(self, size):
        self.size = size
        self.queue = []
        self.top = -1

    def push(self, ele):
        if not self.isFull():
            self.queue.append(ele)
            self.top += 1

        else:
            raise Exception("out of range")

    def isFull(self):
        if self.top == self.size - 1:
            return True
        else:
            return False

    def isEmpty(self):
        if self.size == self.top:
            return True
        else:
            return False

    def pop(self):
        if self.isEmpty():
            raise Exception("no element")
        else:
            ele = self.queue.pop(0)
        return ele

    def returnQueue(self):
        return self.queue


if __name__ == '__main__':
    queue = Queue(10)

    for i in xrange(5):
        queue.push(i)

    print queue.pop(), queue.queue

 然后,就是计算器的整个主程序:

#python
#coding=utf-8
from stack import Stack
from queue import Queue


class RailExpress():
def __init__(self, express):
self.fontExpress = express
self.railExpress = []
self.size = len(express)
self.stack = Stack(self.size)
self.queue = Queue(self.size)

self.level = {'+': 1, '-': 1, '*': 2, '/': 2, '(': 3, ')': 3}
self.operators = ['+', '-', '*', '/', '(', ')']

self.makeRailExpress()

def makeRailExpress(self):
for i in self.fontExpress:
if i in self.operators:
if i is self.operators[-1]:
ele = self.stack.pop()

while ele is not self.operators[-2]:
self.queue.push(ele)
ele = self.stack.pop()

if self.stack.isEmpty():
break

elif i is self.operators[-2]:
self.stack.push(i)

else:
if not self.stack.isEmpty():
while self.stack.returnFristEle() is not self.operators[-2] and self.level[self.stack.returnFristEle()] >= self.level[i]:
ele = self.stack.pop()
self.queue.push(ele)

if self.stack.isEmpty():
break

self.stack.push(i)
else:
self.queue.push(i)

if not self.stack.isEmpty():
stack = self.stack.returnStack()
stack.reverse()
self.queue.returnQueue().extend(stack)


class CheckExpress():
def __init__(self, express):
if len(express) > 10000:
sys.exit(0)
self.express = express

def checkExpress(self):
express = []
count = -1

for each in self.express:
if (each >= '0') and (each <= '9') or (each == '.'):
length = len(express)
if length == 0:
express.append(each)
count += 1

elif (express[count] >= '0') and (express[count] <= '999999') or (each == '.'):
length = len(express)
express[length - 1] = express[length - 1] + each
else:
express.append(each)
count += 1
else:
if each == '+' or each == '-' or each == '*' or each == '/' or each == '(' or each == ')':
express.append(each)
count += 1

return express


class Calculator():
def __init__(self, express):
self.express = express
size = len(express)
self.stack = Stack(size)
self.result = None

self.operatorRailExpress()

def operatorRailExpress(self):
for each in self.express:
if (each >= '0') and (each <= '999999'):
self.stack.push(each)

else:
twoOperator = self.stack.pop()
oneOperator = self.stack.pop()
temp = self.calculator(oneOperator, twoOperator, each)

self.stack.push(temp)

self.result = self.stack.returnFristEle()

def calculator(self, one, two, operator):
operatorDict = {'+': self.plus, '-': self.reduction, '*': self.multiplicate, '/': self.devision}
temp = operatorDict[operator](one, two)

return temp

def plus(self, one, two):
return float(one)+float(two)

def reduction(self, one, two):
return float(one)-float(two)

def multiplicate(self, one, two):
return float(one)*float(two)

def devision(self, one, two):
return float(one)/float(two)


class ConnectView():
def __init__(self, model):
self._model = model

def calculator(self):
express = CheckExpress(self._model.result).checkExpress()
if len(express) == 1:
sys.exit(0)

rail = RailExpress(express)
queue = rail.queue.returnQueue()
if len(queue) == 1:

sys.exit(0)
calculate = Calculator(queue)
self._model.result = str(calculate.result)

import sys
if __name__ == '__main__':
express = raw_input('输入表达式:')

express = CheckExpress(express).checkExpress()
if len(express) == 1:
sys.exit(0)

rail = RailExpress(express)
queue = rail.queue.returnQueue()
if len(queue) == 1:
print int(queue[0])
sys.exit(0)
calculate = Calculator(queue)
print calculate.result
 

上面代码分析如下:

1.中缀表达式转后缀表达式的方法:
⑴.遇到操作数:直接输出(添加到后缀表达式中)
⑵.栈为空时,遇到运算符,直接入栈
⑶.遇到左括号:将其入栈
⑷.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
⑸.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
⑹.最终将栈中的元素依次出栈,输出。

2.首先解释CheckExpress,这个函数主要是将表达式中的改为标准的表达式,将每个元素加入列表中,这里的每个元素只包括“数字”和“+-*/”,空格或者其它的字符会自动过滤。当只输入一个有效字符时,就会终止程序。

3.RailExpress就是求后缀表达式,程序部分的核心;

4.Calculator就是计算后缀表达式的值。

   在此基础上,鄙人用GTK,写了一个简易的计算器界面。算是给这个计算器程序,结了一个尾。界面程序就不贴了~~有意者我们可以私聊~~~嘿嘿·

  由于新手一枚,代码质量确实有限。但是,人都是在不断的磨砺中成长,欢迎大家吐槽~~~

posted on 2015-07-08 10:10  佛系少年  阅读(331)  评论(0编辑  收藏  举报