[Algoritmo gráfico] Calculadora básica: hermoso diseño de cuatro operaciones aritméticas

Resolver una expresión aritmética de cuatro es un problema clásico cuando estudiamos "Estructura de datos (pila)". Y ahora, intentamos romper con el uso de la pila e implementar una aritmética de cuatro con el mismo código hermoso.
 
A continuación, procederemos paso a paso, comenzando con la calculadora de suma y resta más simple, sumando multiplicaciones y divisiones, sumando paréntesis y finalmente presentaremos una calculadora aritmética completa de cuatro. ¡Empecemos> _ <! ! !

 
 
 

Calculadora básica 1-solo suma y resta

entrada: "2 + 3 + 11-6"
salida: 10

La primera pregunta implica una idea importante de este tipo de problema: las cuatro operaciones aritméticas pueden considerarse operaciones de suma.

Es fácil de entender mirando la imagen:
Inserte la descripción de la imagen aquí

Ahora considere una pregunta extremadamente importante: ¿Cuál es la base para dividir operaciones de suma y resta en operaciones de suma en la figura anterior? En otras palabras, cuando pasamos a qué carácter, ¿sabemos que un elemento de suma completa debe segmentarse en este momento?

¿Es un número? Cuando lo atravesamos +, registramos este símbolo; luego lo atravesamos 3y el resultado final es +3. Parece una idea correcta, pero cuando 1se alcanza el recorrido , el programa cree erróneamente que la suma y la división ha terminado, y suma +1 al resultado final, pero en realidad debería ser +11.
 

La división se basa en el signo más / menos. Después de comprender este punto, la idea de esta pregunta está lista para surgir: establecemos un opsbúfer para el llamado último símbolo, establecemos un numregistro del número actual y establecemos uno rescomo resultado final; cuando cel número es atravesado, se registra; cuando el crecorrido alcanza el signo más / menos puesto en un elemento de adición (a opsy numcomposición) se agrega al resultado final; también capunta a más / menos el caché ops, se convierte en un símbolo que ccontinúa moviéndose.

También tenga en cuenta, ¿el último elemento de adición no está dividido? Porque no hay ningún símbolo detrás. Por lo tanto, cuando se recorre hasta el último carácter ( len - 1), también se utiliza como base para dividir el elemento de adición.

Todavía mira la imagen para entender:

Inserte la descripción de la imagen aquí

 

El código se proporciona a continuación (además, 11el manejo de varios dígitos ( ) en este código es muy elegante, preste atención a la experiencia):

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;
    }
}

 
 
 

Calculadora básica 2-suma, resta, multiplicación y división

entrada: "2-3 + 4 * 6 + 2"
salida: 25

Debería poder darse cuenta de inmediato, ¿qué es más que una suma y una resta? prioridad.

No hablemos de prioridad por ahora, primero pensemos si la suma, resta, multiplicación y división se pueden dividir en términos de suma. No solo eso, sino que a partir de la siguiente división, puede comprender mejor por qué la división se basa en números, no en los signos de multiplicación / división, sino en los signos más / menos.

Todavía mira la imagen:
Inserte la descripción de la imagen aquí

El problema de prioridad se resuelve a continuación. No es difícil encontrar que lo anterior +4no se puede apresurar para agregarlo res, por lo que también necesitamos un resultado en caché tmp; cuando se recorre para sumar / restar / multiplicar / dividir, tmpse calcula el último símbolo y el símbolo actual se almacena en caché; solo el transversal al signo más / Solo cuando se agrega el signo menos, la caché se tmpagrega al resultado final res.

Todavía mira la imagen:
Inserte la descripción de la imagen aquí

 
El código se proporciona a continuación:

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;
    }
}

 
 
 

Calculadora básica 3-suma y resta con paréntesis

entrada: "2- (4- (7 + 1))"
salida: 6

¿No es esto también una cuestión de prioridad? ¿Pueden los paréntesis elevar cualquier operación a la máxima prioridad?

No es. Los paréntesis se pueden anidar. Entonces este es un problema recursivo.
 
Seamos más violentos y cortemos la cuerda directamente. Al pasar a los paréntesis, el cntrecuento se utiliza para coincidir con los paréntesis (cuando se encuentra el paréntesis izquierdo, el recuento aumenta en uno; cuando se encuentra el paréntesis derecho, el recuento se reduce en uno); cuando cntvuelve a 0, el contenido dentro del paréntesis más grande se usa como una nueva expresión. Se realiza la recursividad y se asigna el resultado del cálculo devuelto por la recursividad num.

Todavía mira la imagen:
Inserte la descripción de la imagen aquí

 
El código se proporciona a continuación (sobre la base del código básico de la calculadora 1, se agrega el tratamiento de paréntesis):

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;
    }
}

 
 
 

Calculadora básica 4-cuatro aritmética (suma, resta, multiplicación y división con paréntesis)

Combinando todos los pensamientos anteriores:

1) Cuatro operaciones aritméticas se pueden considerar como elementos de suma múltiple

2) La base para dividir elementos de suma no son números, ni signos de multiplicación / división, ni paréntesis, sino signos más / menos

3) Recorrer al número, sin registro cerebral; Recorrer al símbolo, calcular el símbolo anterior

3) Los problemas de prioridad causados ​​por la multiplicación y la división se resuelven con resultados almacenados en caché

4) El problema de prioridad causado por los paréntesis se resuelve con una cadena recursiva

Y algunos detalles para hacer el código más elegante y robusto:

1) El último carácter también se utiliza como signo para cortar y agregar elementos.

2) Procesamiento de varios dígitos

3) Tratamiento de caracteres vacíos en expresiones

el código se muestra a continuación:

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 L o l i is esyo es elt h e MEJOR MEJORB E S T y yun n d preciosasP R E C I O U S obsequio regalog i f t eni n el lat h e mundo. mundo.w o r l d .

Supongo que te gusta

Origin blog.csdn.net/m0_46202073/article/details/114729707
Recomendado
Clasificación