(Ejercicio de algoritmo) Suma binaria

Leetcode el problema del algoritmo anterior: ( https://leetcode-cn.com/problems/add-binary/ )

Dadas dos cadenas binarias, devuelve su suma (en representación binaria).

La entrada es una cadena no vacía y solo contiene los números 1 y 0.

Ejemplo 1:

Entrada: a = "11", b = "1"
Salida: "100"


Ejemplo 2:

Entrada: a = "1010", b = "1011"
Salida: "10101"

Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/add-binary

Principales puntos de conocimiento a investigar:

1. El valor ASCII del carácter actual menos el valor ASCII de "0" equivale a convertir este carácter en un valor numérico.

2. StringBuilder la  StringBuffer diferencia

3. El método de inversión de caracteres reverse ();

4. Cálculo de la complejidad del tiempo

Ideas de implementación:

La idea general es completar las dos cadenas más cortas con 00 para hacer que las dos cadenas tengan la misma longitud y luego recorrer el cálculo desde el final para obtener el resultado final.

La idea general en la solución de esta pregunta es la misma que la anterior, pero debido a razones de manipulación de cadenas, no está claro si el resultado final tendrá un acarreo más, por lo que hay dos formas de abordarlo:

El primer tipo es concatenar directamente la cadena durante el cálculo, y obtendrá un carácter inverso, que debe invertirse al final.
El segundo tipo es asignar el carácter de resultado según la posición y, finalmente, si hay un acarreo , la cuerda se empalmará al frente para agregar el transporte

Opción 1: Código relevante (p. Ej. Dado que los puntos de conocimiento de Asscii son puntos ciegos, también lo escribí oración por oración, mientras escribía y entendía las ideas, agregando comentarios)

class Solution {
    public String addBinary(String a, String b) {
        int aLen = a.length();
        int bLen = b.length();
        int maxLen = Math.max(aLen,bLen);
        
        //字符串进行翻转
        StringBuilder sbA = new StringBuilder(a).reverse();
        StringBuilder sbB = new StringBuilder(b).reverse();
        
        //让两个字符串补齐成一个长度,翻转过后前置位补0
        while(sbA.length() < maxLen){
            sbA.append("0");
        }
        
        while(sbB.length() < maxLen){
            sbB.append("0");
        }
    
        StringBuilder res = new StringBuilder();
        
        //进位的标志位, 默认是0
        int carry = 0;
        
        //知识点:当前字符的 ASCII 值减去 '0' 的 ASCII 值,相当于将这个字符转换成数值
        int num1;
        int num2;
        
        for(int i=0; i < maxLen; i++){
            num1 = sbA.charAt(i) - '0';    
            num2 = sbB.charAt(i) - '0';
            
            if(carry + num1 + num2 > 1){
                //1+1的情况,在二进制下 需要减去2
                res.append(carry + num1 + num2 - 2);
                
                //表示 需要进位,改变标志位
                carry = 1;
            }else{
               res.append(carry + num1 + num2);
               carry = 0; 
            }
        }
        
        //对于最高位 需要增加位数,如果存在进位的情况
        if(carry == 1){
            res.append("1");
        }
        
        //最后再翻转一次,为开始补位的时候就是翻转后的
        return res.reverse().toString();
        
    }
    
}

Opción 2: Código relacionado (también escribí ps oración por oración, comprendí las ideas mientras escribía y agregué comentarios)

El código anterior se "voltea" dos veces, lo cual es un poco detallado. Podemos usar dos punteros para avanzar desde el final de la cadena y, al mismo tiempo, tomar prestado el método de inserción del objeto StringBuilder para obtener los resultados del cálculo desde la derecha. a izquierda., Realmente está muy cerca del proceso de "adición vertical" a mano. El siguiente es el código de referencia (extraído de la solución)

    private String doAddWithInsert(String a, String b){
        int i = a.length() - 1;
        int j = b.length() - 1;
        
        //这个是结果: 可变的字符序列对象
        StringBuilder res = new StringBuilder();
        
        int curSum;
        
        //进位的标志位
        int carry = 0;
        
        while(i >=0 || j >=0){
            curSum = carry;
            
            //当前位置的a的i位和 b 的j 位,都是末位进行相加
            if(i >= 0){
                curSum += a.charAt(i) - '0';
                i--;
            }    
            
            if(j >= 0){
                curSum += b.charAt(j) - '0';
                j--;
            }
            
            //判断是否需要进位
            if(curSum > 1){
                //1+1的情况,在二进制下 需要减去2,有进位
                curSum -= 2;
                carry = 1;
            }else{
                carry = 0;
            }          
            
            // 只写结果的值,进位作为下一轮的初始值
            res.insert(0, curSum);
            
        }
        
        if(carry == 1){
            res.insert(0, 1);
        }
        
        return res.toString();
        
    }

La solución uno puede ser más fácil de entender, pero la solución dos está más en línea con la idea de la suma vertical.

 

Supongo que te gusta

Origin blog.csdn.net/android_freshman/article/details/101695928
Recomendado
Clasificación