[Graphic Algorithm] Basic calculator-beautiful design of four arithmetic operations

Solving a four arithmetic expression is a classic problem when we study "Data Structure (Stack)". And now, we try to break away from the use of the stack and implement a four arithmetic with the same beautiful code.
 
Below, we will proceed step by step, starting from the simplest addition and subtraction calculator, adding multiplication and division, adding parentheses, and finally present a complete four arithmetic calculator. Let's start>_<! ! !

 
 
 

Basic calculator 1-only addition and subtraction

input:“2+3+11-6”
output:10

The first question involves an important idea of ​​this type of problem: all four arithmetic operations can be regarded as addition operations.

It is easy to understand by looking at the picture:
Insert picture description here

Now consider an extremely important question. What is the basis for dividing addition and subtraction operations into addition operations in the above figure? In other words, when we traverse to what character, we know that a complete addition item should be segmented at this time?

Is it a number? When we traverse to it +, we record this symbol; then we traverse to it 3, and the final result is +3. It seems to be a correct idea, but when the traversal 1is reached, the program mistakenly believes that the addition and division is over, and adds +1 to the final result, but in fact it should be +11.
 

The division is based on the plus/minus sign. After understanding this point, the idea of ​​this question is ready to come out: we set a opsbuffer for the so-called last symbol, set a numrecord of the current number, and set one resas the final result; when cthe number is traversed, it is recorded; when the ctraversal reaches the plus/minus sign put on an addition item (a opsand numcomposition) is added to the final result; also cpoints to plus / minus the cache ops, become a symbol ccontinues to move.

Also note, is the last addition item undivided? Because there is no symbol behind it. Therefore, when traversing to the last character ( len - 1), it is also used as the basis for dividing the addition item.

Still look at the picture to understand:

Insert picture description here

 

The code is given below (in addition, 11the handling of multiple digits ( ) in this code is very elegant, pay attention to experience):

class Solution {
    
    
    public int calculate(String s) {
    
    
        int num = 0;        // 记录的数字(看看它在上图中的位置)
        char ops = '+';     // 缓存的符号(看看它在上图中的位置)
        int res = 0;        // 最终结果

        for (int i = 0; i < s.length(); i++) {
    
    
            char c = s.charAt(i);
            // 如果是数字
            if (Character.isDigit(c)) {
    
    
                num = num * 10 + c - '0';
            }
            // 如果是加减
            if (c == '+' || c == '-' || i == s.length() - 1) {
    
    
                switch (ops) {
    
    
                    case '+': res += num; break;
                    case '-': res -= num; break;
                }
                num = 0;
                ops = c;
            }
        }
        return res;
    }
}

 
 
 

Basic calculator 2-addition, subtraction, multiplication and division

input:“2-3+4*6+2”
output:25

You should be able to realize immediately, what is more than addition and subtraction? priority.

Let's not talk about priority for the time being, first think about whether addition, subtraction, multiplication, and division can be divided into addition terms. Not only that, but from the following division, you can better understand why the division is based on numbers, not multiplication/division signs, but plus/minus signs.

Still look at the picture:
Insert picture description here

The priority issue is solved below. It is not difficult to find that the above +4cannot be rushed to append to resit, so we also need a cached result tmp; when traversing to add/subtract/multiply/divide, the tmplast symbol is calculated and the current symbol is cached; only the traversal to the plus sign/ Only when the minus sign is added, the cache is tmpadded to the final result res.

Still look at the picture:
Insert picture description here

 
The code is given below:

class Solution {
    
    
    public int calculate(String s) {
    
    
        int num = 0;        // 记录的数字
        char ops = '+';     // 缓存的符号
        int tmp = 0;        // 缓存结果
        int res = 0;        // 最终结果

        for (int i = 0; i < s.length(); i++) {
    
    
            char c = s.charAt(i);
            // 如果是数字
            if (Character.isDigit(c)) {
    
    
                num = num * 10 + c - '0';
            }
            // 如果是符号
            if (c == '+' || c == '-' || c == '*' || c == '/' || i == s.length() - 1) {
    
    
                switch (ops) {
    
    
                    case '+': tmp += num; break;
                    case '-': tmp -= num; break;
                    case '*': tmp *= num; break;
                    case '/': tmp /= num; break;
                }
                if (c == '+' || c == '-' || i == s.length() - 1) {
    
    
                    res += tmp;
                    tmp = 0;
                }
                num = 0;
                ops = c;
            }
        }
        return res;
    }
}

 
 
 

Basic calculator 3-addition and subtraction with parentheses

input:“2-(4-(7+1))”
output:6

Isn't this also a matter of priority? Can parentheses raise any operation to the highest priority?

It's not. Parentheses can be nested. So this is a recursive problem.
 
Let's be more violent and cut the string directly. When traversing to the parentheses, the cntcount is used to match the parentheses (when the left parenthesis is encountered, the count is increased by one; when the right parenthesis is encountered, the count is decreased by one); when it cntreturns to 0, the content inside the largest parenthesis is used as a new expression Recursion is performed, and the calculation result returned by recursion is assigned to num.

Still look at the picture:
Insert picture description here

 
The code is given below (on the basis of the basic calculator 1 code, the treatment of parentheses is added):

class Solution {
    
    
    public int calculate(String s) {
    
    
        int num = 0;        // 记录的数字
        char ops = '+';     // 缓存的符号
        int res = 0;        // 最终结果

        for (int i = 0; i < s.length(); i++) {
    
    
            char c = s.charAt(i);
            // 如果是括号
            if (c == '(') {
    
    
                int cnt = 0;
                int t = i;
                for (; i < s.length(); i++) {
    
    
                    if (s.charAt(i) == '(')  cnt++;
                    if (s.charAt(i) == ')')  cnt--;
                    if (cnt == 0) {
    
    
                        break;
                    }
                }
                num = calculate(s.substring(t + 1, i));
            }
            // 如果是数字
            if (Character.isDigit(c)) {
    
    
                num = num * 10 + c - '0';
            }
            // 如果是加减
            if (c == '+' || c == '-' || i == s.length() - 1) {
    
    
                switch (ops) {
    
    
                    case '+': res += num; break;
                    case '-': res -= num; break;
                }
                num = 0;
                ops = c;
            }
        }
        return res;
    }
}

 
 
 

Basic calculator 4-four arithmetic (addition, subtraction, multiplication and division with parentheses)

Combining all the above thoughts:

1) Four arithmetic operations can be regarded as multiple addition items

2) The basis for dividing addition items is not numbers, not multiplication/division signs, not parentheses, but plus/minus signs

3) Traverse to the number, no brain record; Traverse to the symbol, calculate the previous symbol

3) Priority problems caused by multiplication and division are solved with cached results

4) The priority problem caused by parentheses is solved with a recursive string

And some details to make the code more elegant and robust:

1) The last character is also used as a sign for cutting and adding items

2) Processing of multiple digits

3) Treatment of empty characters in expressions

code show as below:

class Solution {
    
    
    public int calculate(String s) {
    
    
        int num = 0;        // 当前的数字
        char ops = '+';     // 当前的数字之前的符号
        int tmp = 0;        // 临时结果
        int res = 0;        // 最终结果

        for (int i = 0; i < s.length(); i++) {
    
    
            char c = s.charAt(i);
            // 如果是括号
            if (c == '(') {
    
    
                int cnt = 0;
                int t = i;
                for (; i < s.length(); i++) {
    
    
                    if (s.charAt(i) == '(')  cnt++;
                    if (s.charAt(i) == ')')  cnt--;
                    if (cnt == 0) {
    
    
                        break;
                    }
                }
                num = calculate(s.substring(t + 1, i));
            }
            // 如果是数字
            if (Character.isDigit(c)) {
    
    
                num = num * 10 + c - '0';
            }
            // 如果是符号
            if (c == '+' || c == '-' || c == '*' || c == '/' || i == s.length() - 1) {
    
    
                switch (ops) {
    
    
                    case '+': tmp += num; break;
                    case '-': tmp -= num; break;
                    case '*': tmp *= num; break;
                    case '/': tmp /= num; break;
                }
                if (c == '+' || c == '-' || i == s.length() - 1) {
    
    
                    res += tmp;
                    tmp = 0;
                }
                num = 0;
                ops = c;
            }
        }
        return res;
    }
}

 
 
 
 

 
 
 
 

 
 
 
 

 
 
 
 

L oli Loli Loli i s is is t h e the the B E S T BEST BEST a n d and and P R E C I O U S PRECIOUS PRECIOUS g i f t gift gift i n in in t h e the the w o r l d . world. world.

Guess you like

Origin blog.csdn.net/m0_46202073/article/details/114729707