Day4 calculator, day4

Source: Internet
Author: User

Day4 calculator, day4

Job: calculator Development

(1) implements addition, subtraction, multiplication, division, and extension priority resolution;

(2) user input 1-2*(60-30 + (-40/5) * (-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14)-(-4*3)/(16-3*2 )) after a similar formula is used, you must parse the (), +,-, *,/, and formula in it and calculate the result, the result must be consistent with the result obtained by the real calculator.

The Code is as follows:

 

1 import re 2 3 formula = '1-2*(60-30 + (-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14) * (-40/5)-(-4*3)/(16-3*2) '4 # formula = "(1 + + 1) "5 def modify (formula_deep): 6''' program modifier, remove spaces and parentheses '''7''' to remove the +--- ++ +-+ and other situations in the Operation '''8 formula_deep = re. sub ("[()]", "", formula_deep) # Replace space and empty number 9 formula_deep = re. sub ("\ +-", "-", formula_deep) # Replace +-with-10 formula_deep = re. sub ("--", '+', formula_deep) # Replace -- with + 11 formula_deep = re. sub ("-\ +", '-', formula_deep) 12 formula_deep = re. sub ("\ ++", "+", formula_deep) 13 return formula_deep14 15 def multiply_divide (formula_deep ): 16 ''' calculate multiplication and division ''' 17''' because multiplication and division are the first calculation, our idea is to calculate multiplication and division first and then replace the calculation result, you can get the '''18 calc_sign = re. findall ("[+-]", formula_deep) # extract all addition and subtraction numbers in the string 19 calc_list = re. split ("[+-]", formula_deep) # Use the plus or minus sign to separate the 20 '''. Because of the calc_list: ['', '9 ', '2*5/', '3', '2017*7/3*99/4*2998', '10*568/14 '], in which-9 is split due to the trouble caused by the-number, 2*5/equal to '''21 if calc_list [0] = '': 22''' when" at the beginning of the processing list is null, it indicates that this is a negative number, split to merge ''' 23 calc_list [1] = calc_sign [0] + calc_list [1] 24 del calc_sign [0] 25 del calc_list [0] 26 for num, line in enumerate (calc_list): 27 ''' when processing 2*5/, it indicates that this is followed by a negative number, only a negative number is used to split 2*5/-3. You need to merge '''28 if line. endswith ("/") or line. endswith ("*"): 29, the negative number is split into '''30 calc_list [num + 1] = calc_list [num] + calc_sign [num] + calc_list [num + 1] 31 del calc_sign [num] 32. del calc_list [num] 33''' performs the multiplication and division operation, the above are all formatted conversion ''' 34 for index, string in enumerate (calc_list): 35''' first extract the number, the calculated value '''36 if "/" in string or "*" in string: 37 mul_div_sign = re. findall ("[/*]", string) 38 mul_div_list = re. split ("[/*]", string) 39 calc_value = None40 for e_index, e in enumerate (mul_div_list): 41 if calc_value: 42 if mul_div_sign [e_index-1] = "/": 43 calc_value/= float (e) 44 elif mul_div_sign [e_index-1] = "*": 45 calc_value * = float (e) 46 else: 47 calc_value = float (e) 48 calc_list [index] = calc_value49 else: 50 pass51 ''' calculated value ''' 52 value = None53 for k, v in enumerate (calc_list): 54 ''' calculate addition and subtraction ''' 55 if value: 56 if calc_sign [k-1] = "-": 57 value-= float (v) 58 elif calc_sign [k-1] = '+': 59 value + = float (v) 60 else: 61 value = float (v) 62 return value63 64 65 def main (formula): 66 ''' main Entrance of the program, generate the case with parentheses ''' 67 while True: 68 formula_deep = re. search ("\(. [^ ()] + \) ", formula) 69 if formula_deep: 70 formula_deep = formula_deep.group () 71 formula_list = modify (formula_deep) 72 ''' to obtain the string to be calculated, now start computing-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14 ''' 73 calc_value = multiply_divide (formula_list) 74 formula = formula. replace (formula_deep, str (calc_value) 75 else: 76''' handle situations without parentheses ''' 77 formula = modify (formula) 78 calc_last_value = multiply_divide (formula) 79 print ("formula:", calc_last_value) 80 exit () 81 82 if _ name __= = "_ main _": 83 main (formula)

 

Program running process:

General idea: we know that to calculate the format of the above string, you can use the eval () function, but here we need to write a calculator by ourselves; we know, the priority of mathematical operations is the highest priority of parentheses. We first calculate the content in parentheses. Therefore, our idea is to match the memory parentheses and then perform operations, after matching the content in the memory parentheses, we calculate and use the calculated value to replace the original position value in the string, and always replace it with the string without the bracket position, in this case, we perform the calculation according to the normal operation order.

1. Regular Expression matching. First, find the memory parentheses. The Code is as follows:

Formula = '1-2*(60-30 + (-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14) * (-40/5 )) -(-4*3)/(16-3*2 ))'
Formula_deep = re. search ("\ (. [^ ()] + \)", formula)
Print (formula_deep.group ())

The running result is as follows:

(-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14)

As we can see from the above observations, we can see that there are many places that need to be modified. There are many null strings, which will affect our computation, and we do not need parentheses during the computation process, therefore, remove the brackets.

2. Remove spaces and parentheses;

Formula_deep = re. sub ("[()]", "", formula_deep)

Run the following command:

-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14
3. After obtaining the preceding string, we can perform layer-by-layer operations, such as +-,-+, ++, and --. At this time, we need to process the string, because it is the first layer, we cannot see the problem. After the calculation, if the memory gets a negative number, if it is + or-outside the brackets, it will become +-, --, and so on, this is not the case at this time. You must also handle it;

Formula_deep = re. sub ("\ +-", '-', formula_deep)
Formula_deep = re. sub ("-+", '-', formula_deep)
Formula_deep = re. sub ("\ ++", "+", formula_deep)
Formula_deep = re. sub ("--", '+', formula_deep)
Run the following command:

-9-2*5/-3 + 7/3*99/4*2998 + 10*568/14

4. After the above processing is complete, the computing will officially start. We know that computing must first calculate the multiplication and division, because the multiplication and division have the highest priority, because we must first find the multiplication and division, after the calculation is complete, add or subtract the value;

Calc_sign = re. findall ("[+-]", formula_deep)
Calc_list = re. split ("[+-]", formula_deep)
Print (calc_list)
Print (calc_sign)

Run the following command:

['', '9', '2*5/', '3', '2017*7/3*99/4*2998', '10*568/14 ']
['-', '+', '+']

We get the calculated list, and the operator number, ['', '9', '2*5/', '3', '2017*7/3*99/4 ', there is also a problem in '10*568/14 ']. First, the first element in the list is "" null, indicating that the first element is the-number, this case is to be merged, and there are still 2*5/. This indicates that the following is also a negative number. We also need to handle the problem before calculating the plan. Why does this happen? This is because in the operation process, we use "+" or "-" to split the string, which will lead to a negative number, which will be split, at the beginning, an empty field is split, which may cause an operation error because modification is required.

5. Modify the preceding operations:

If calc_list [0] = "":
Calc_list [1] = calc_sign [0] + calc_list [1]
Del calc_list [0]
Del calc_sign [0]
Print ("calc_list:", calc_list)
Print ("calc_sign:", calc_sign)
For index, e in enumerate (calc_list ):
If e. endswith ("/") or e. endswith ("*"):
''' Indicates that the number following it is a negative number. Modify '''
Calc_list [index + 1] = calc_list [index] + calc_sign [index] + calc_list [index + 1]
Del calc_list [index]
Del calc_sign [index]

Print ("calc_list:", calc_list)
Print ("calc_sign:", calc_sign)

Run the following command:

Calc_list: ['-9', '2*5/', '3', '2017*7/3*99/4 ', '10*2998']
Calc_sign: ['-', '-', '+', '+']
Calc_list: ['-9', '2*5/-3', '2017*7/3*99/4', '10*2998 ']
Calc_sign: ['-', '+', '+']

From the above we can see that we have made two corrections, removing the "" Empty element at the beginning for the first time; and proposing the multiplication and division followed by a negative number for the second time;

6. At this time, we will calculate the number. First, we traverse calc_list: ['-9', '2*5/-3', '2017*7/3*99/4 ', elements in '10*568/14 ']. Because we need to multiply and divide the elements first, find the string containing "/" or "*", evaluate the value, and then replace it, you can get a string without multiplication and division, only including addition and subtraction:

For num, value in enumerate (calc_list): if "/" in value or "*" in value: "indicates that multiplication and division are included. Calculate" mul_div_sign = re. findall ("[/*]", value) mul_div_list = re. split ("[*/]", value) print (mul_div_sign) print (mul_div_list)

The calculation result is as follows:

['*', '/']
['2', '5', '-3']
['/', '*', '/', '*']
['7', '3', '99', '4', '123']
['*', '/']
['10', '123', '14']

We get the operator and the number in it. Now we only need to judge the multiplication and division number, and then we can use the previous one multiplied by the next one for calculation. As follows:

7. multiplication and division calculation:

1 for num, value in enumerate (calc_list): 2 if "/" in value or "*" in value: 3 "indicates multiplication and division, calculate "4 mul_div_sign = re. findall ("[/*]", value) 5 mul_div_list = re. split ("[*/]", value) 6''' next, we calculate the multiplication and division. First, we need to traverse the division, because you want to pass the element '''7 res = None 8 for e_index, e_value in enumerate (mul_div_list): 9 if res: 10 if mul_div_sign [e_index-1] = "/": 11 res/= float (e_value) 12 elif mul_div_sign [e_index-1] = "*": 13 res * = float (e_value) 14 else: 15 res = float (e_value) # If it does not exist, a new one is generated, but we define that it does not exist. Therefore, it must be a single number, and then 16 calc_list [num] = res17 else is calculated: 18 pass19 20 print (calc_list) 21 print (calc_sign)

The running result is as follows:

['-9',-3.3333333333333335, 173134.50000000003, 405.7142857142857]
['-', '+', '+']

In the above Code, we perform the multiplication and division operation so that there is no multiplication and division in the operation. We only need to perform the addition and subtraction operation.

We can see that after calculation, only addition and subtraction are left, so that we can use the list elements and symbols for addition and subtraction.

8. addition and subtraction:

1 ''': '''2 result = None 3 for k_index, k_value in enumerate (calc_list): 4 if result: 5 if calc_sign [k_index-1] = "+": 6 result + = float (k_value) 7 elif calc_sign [k_index-1] = '-': 8 result-= float (k_value) 9 else: 10 result = float (k_value) 11 print ("result:", result)

Run the following command:

Result: 173534.54761904766

9. above, we get the calculation result, and then we only need to replace the content of the memory parentheses. In this case, a layer of replacement will only result in the calculation without parentheses. At this time, in this line, we can get the final result.

Knowledge point:

(1 ):

result = None
for k_index,k_value in enumerate(calc_list):
if result:
if calc_sign[k_index-1] == "+":
result += float(k_value)
elif calc_sign[k_index-1] == '-':
result -= float(k_value)
else:
result = float(k_value)

The above Code embodies an idea. Because we want to add the last digit to the previous digit, but there is no direct method, we can define a null value first, then we can determine the value. In fact, the purpose of the judgment is to assign a value to this variable. The value assignment is the first element in the list, in this way, the elements in the list are superimposed or stacked and subtracted each cycle. This idea is good. If it does not exist and you want it to exist, you need to define a null value for judgment and assign a value after judgment. After a value is assigned, the result is equal to the first value of the element, and the next cycle of the element also starts from the second value. The length index of the list does not exceed the standard.

2. Use of regular expressions, re (abbreviation of regular ):

^ Indicates non, "\" indicates escape, indicating the meaning of the character, and + indicates one or more

"\ (. [^ ()] + \)" Indicates matching brackets. The brackets contain any number of elements that are not (), that is, matching the innermost brackets.

3. In the string replace () method, the string is searched and replaced, str. replace (old, new), the string findall () in the regular expression to find the value of all the regular expressions in the element, put it in a list; re. the split () string is separated by a regular string.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.