Use Python to calculate a string expression
Overview: how to run an expression, such as 12 + 23*4/2. But what if this expression is a string? Or how can we run and obtain a value when an expression is written as a string? Would you think, if we can get 12, 23, 4, 2 and the middle operator, it would be really good. In fact, we are working in this direction. If you have learned algorithms or data structures, I think this small problem won't stop you from moving forward.
Train of Thought Analysis: As described in the summary, if we can get the "elements" that we can recognize with the naked eye in the string expression, we will take the first step. What! The first step? Yes, this is the first step. What is the second step?
That's right. The second step is the calculation. There is a problem in the operation process. This problem is the operator priority. Taking the above expression as an example, we need to perform the 23*4 operation first, instead of the 12 + 23 operation. What we need to do is let the computer calculate based on our cognitive priority. The stupid method is to traverse the expressions two times in sequence (in fact, in the later calculation, we traverse a list ). Perform multiplication and division for the first time, and perform addition and subtraction for the second time.
Element Separation: This step is really easy to do in Python, because we are cute
Python can store different types of objects in the list.. This is a bit like a struct in C and a class in Java. We first get the characters one by one, and then traverse and classify these characters (whether it is a number or an operator ).
# split expressiondef 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
Logical operation: this function has some special features and may be familiar to friends with programming experience. Yes, that is
Recursion! For a coder, recursion must be mastered. Let's start recursion when appropriate. The reason for recursion is that every operator in our expression cannot have only one. We will continue to traverse it like this. At this time, you may already feel that, if traversing, why not use? Yes, there is also the for loop code in my code, but here the for is not as easy as you can imagine. If you don't believe it, try it.
# 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)
Note: of course, this program is not so robust. Because the premise of our logic is that we get a normal expression without parentheses. The so-called normal expression, that is, there will be no characters or character sets that contain less numbers, fewer operators, or that are not '+', '-', '*', '/', or [0-9. Our program defaults to an ideal running environment, because it only describes the code idea.
Complete code:
#!/usr/bin/env python'expression_cal.py -- cal the expression that you give to me'# judgment a char is a operation or notdef is_operation(oper): if oper == '+' or oper == '-' or oper == '*' or oper == '/': return True else: return False# split expressiondef 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 bdef 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 expdef 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'