运行截图:
其实,python本来就是一个很强大的计算器:^_^,
Source Code:
__author__ = ‘Joel‘ class ExpStack(): #init method def __init__(self): self.top = -1 self.data = [] #whether Stack is empty def is_empty(self): return -1 == self.top #pop an element from stack def pop(self): if self.is_empty(): print "Stack is Empty..." else: self.data.pop(self.top) self.top -= 1 #push an element into stack def push(self, e): self.data.append(e) self.top += 1 #get an element in the top of the stack def get_top(self): if self.is_empty(): print "Stack is Empty" return None else: return self.data[self.top] #get the size of the stack def size(self): return self.top + 1 #clear stack def clear(self): self.top = -1 self.data = [] #get data of stack def get_data(self): return self.data #whether a char is a number def is_number(char): return ("0" == char or "1" == char or "2" == char or "3" == char or "4" == char or "5" == char or "6" == char or "7" == char or "8" == char or "9" == char) #whether a char is dot def is_dot(char): return "." == char #whether a char is calculator operation def is_calculator_option(char): return ("+" == char or "-" == char or "*" == char or "/" == char or "(" == char or ")" == char or "^" == char) #get calculator string def get_calculator_str(): return raw_input("Please input calculator string(no ‘=‘) end with ‘-1‘:\n") #whether a string consists of numbers def is_number_str(m_str): for n in m_str: if (not is_number(n)) and (not is_dot(n)): return False return True #filter blanks from a string def str_trim(src_str): ret_str = "" for c in src_str: if " " != c: ret_str += c return ret_str #filter useless characters from a string def str_filter(src_str): ret_str = "" for c in src_str: if is_number(c) or is_calculator_option(c) or is_dot(c): ret_str += c return ret_str #print elements in the stack def print_calculator_stack(stack): print "---stack content---" print stack.get_data() print #compare operators, return an integer #1: higher priority; 0:lower priority; -1:wrong operator; 2:same priority def compare_operator(op1, op2): if "^" == op1: if "^" == op2: return 2 elif "+" == op2 or "-" == op2 or "*" == op3 or "/" == op3: return 1 else: return -1 elif "*" == op1 or "/" == op1: if "^" == op2: return 0 elif "*" == op2 or "/" == op2: return 2 elif "+" == op2 or "-" == op2: return 1 else: return -1 elif "+" == op1 or "-" == op1: if "^" == op2 or "*" == op2 or "/" == op2: return 0 elif "+" == op2 or "-" == op2: return 2 else: return -1 else: return -1 #get all elements from calculator string and return a stack def get_calculator_stack(cal_str): exp_stack = ExpStack() ele = "" # one element, a number or operator get_a_number = False # whether get a number #if calculator string start with "-(", push 0 in the bottom of the stack if len(cal_str) > 2 and "-" == cal_str[0] and "(" == cal_str[1]: exp_stack.push("0") for tem_char in cal_str: if (((not get_a_number) and "-" == tem_char) or (not is_calculator_option(tem_char))): # is a number ele += tem_char get_a_number = True else: # is a operator if "" != ele: exp_stack.push(ele) ele = "" exp_stack.push(tem_char) if ")" != tem_char: # is ) get_a_number = False else: # is ( get_a_number = True if len(ele) != 0: exp_stack.push(ele) return exp_stack #turn prefix stack into suffix stack def prefix_to_suffix(prefix_stack): data = prefix_stack.get_data() suffix_stack = ExpStack() tem_stack = ExpStack() get_a_number = False get_a_operator = False for ele in data: if is_number_str(ele): # is number, put it into suffix get_a_operator = False if get_a_number: suffix_stack.push(ele) suffix_stack.push("*") else: suffix_stack.push(ele) get_a_number = True elif "(" == ele: # is (, push elements into stack tem_stack.push(ele) elif ")" == ele: # is ), while "(" != tem_stack.get_top(): suffix_stack.push(tem_stack.get_top()) tem_stack.pop() if tem_stack.is_empty(): print "Brackets not match!" return None if "(" == tem_stack.get_top(): tem_stack.pop() elif is_calculator_option(ele): # is operator get_a_number = False if get_a_operator: # no numbers between 2 operators print "Wrong Exps." return None else: get_a_operator = True while ((not tem_stack.is_empty()) and "(" != tem_stack.get_top() and compare_operator(tem_stack.get_top(), ele)>0): suffix_stack.push(tem_stack.get_top()) tem_stack.pop() tem_stack.push(ele) while not tem_stack.is_empty(): if "(" == tem_stack.get_top(): print "Brackets not match!" return None suffix_stack.push(tem_stack.get_top()) tem_stack.pop() return suffix_stack #calculate from stack, return result string def calculate_from_stack(suffix_stack): error_str = "error" nan_str = "NaN" if None == suffix_stack: print "stack is empty!" return error_str data = suffix_stack.get_data() calculate_stack = ExpStack() for ele in data: if is_number_str(ele): calculate_stack.push(ele) elif is_calculator_option(ele): if calculate_stack.size()<2: print "Wrong suffix exps." print_calculator_stack(suffix_stack) return error_str try: num1 = float(calculate_stack.get_top()) calculate_stack.pop() num2 = float(calculate_stack.get_top()) calculate_stack.pop() if "+" == ele: calculate_stack.push(num1+num2) elif "-" == ele: calculate_stack.push(num2-num1) elif "*" == ele: calculate_stack.push(num2*num1) elif "/" == ele: calculate_stack.push(num2/num1) elif "^" == ele: calculate_stack.push(num2**num1) else: print "Unknow calculator operator", ele return error_str except TypeError, e: print "type error:", e return error_str except ValueError, e: print "value error:", e return error_str except ZeroDivisionError, e: print "divide zero error: e" return nan_str if 1 == calculate_stack.size(): return str(calculate_stack.get_top()) else: print "Unknow error, calculate stack:" print_calculator_stack(calculate_stack) return error_str ########### several test function ############ def test_stack(): my_stack = ExpStack() print my_stack.is_empty() my_stack.push("1") my_stack.push(2) my_stack.push(3.14) print my_stack.is_empty() print my_stack.get_data() print my_stack.size() print_calculator_stack(my_stack) def test_isnum(): num = ["1", "2", 1., ‘0‘] i = 0 while i < len(num): if is_number(num[i]): print num[i], " is number" else: print num[i], "is not number" i += 1 ########### END ############ def main(): if __name__ == "__main__": cal_str = get_calculator_str() cal_str = str_filter(cal_str) # filter string # main loop while "-1" != cal_str: prefix_stack = get_calculator_stack(cal_str) print "cal str:", cal_str print "prefix stack:" print_calculator_stack(prefix_stack) # make prefix to suffix suffix_stack = prefix_to_suffix(prefix_stack) print "suffix stack:" print_calculator_stack(suffix_stack) # calculate suffix print "---calculator result---" print calculate_from_stack(suffix_stack) cal_str = get_calculator_str() cal_str = str_filter(cal_str) # filter string print "bye~" else: print __name__ #the main! main()