Nowcoder NC10 Multiplicación de números grandes

Enlace de pregunta:  icono-default.png?t=N7T8https://www.nowcoder.com/practice/c4c488d4d40d4c4e9824c3650f7d5571?tpId=196&tqId=37177&rp=1&ru=/exam/company&qru=/exam/company&sourceUrl=%2Fexam%2Fcompany&difficulty=undefinido&judgeStatu s= indefinido&etiquetas=&título=

Tabla de contenido

Tema Descripción:

Respuesta:

Explicación detallada: 


Tema Descripción:

Lea dos números como cadenas, escriba una función que calcule su producto y los devuelva como una cadena.

Rango de datos: el tamaño del número leído satisface 0 \leqslant n \leqslant {10}^{1000}

Requisitos: complejidad espacial O (m), complejidad temporal O ( m^{2}) (suponiendo que m es la longitud de n)

Ejemplo 1:

Entrada: "11","99"

Valor de retorno: "1089"

Descripción: 11*99=1089

Ejemplo 2:

Entrada: "1","0"

Valor de retorno: "0"

Respuesta:

import java.util.*;


public class Solution {

    public String solve (String s, String t) {
        // write code here
        if (s.charAt(0) == '0' || t.charAt(0) == '0'){
            return "0";
        }
        String ret = "0";
        String[] tmp = new String[t.length()]; 
        for (int i = t.length() - 1; i >= 0; i--){
            tmp[i] = "";
            int j = t.length() - 1;
            while(j - i > 0){
                tmp[i] += '0';
                j--;
            }
            tmp[i] += alongMultiply(s, t.charAt(i));
        }
        for (int i = t.length() - 1; i >= 0; i--){
            ret = Add(tmp[i], ret);
        }
        
        //将结果逆置
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = ret.length() - 1; i >= 0; i--){
            stringBuffer.append(ret.charAt(i));
        }
        ret = stringBuffer.toString();
        //也可以写成这样
        //tmp[0] = ret;
        //ret = "";
        //for (int i = tmp[0].length() - 1; i >= 0; i--){
        //    ret += tmp[0].charAt(i);
        //}
        return ret;
    }

    public String Add(String a, String b){
        String str = "";
        int aLen = a.length() - 1;
        int ai = 0;
        int bLen = b.length() - 1;
        int bi = 0;
        int ten = 0;

        while(aLen >= ai && bLen >= bi){
            int tmp = (a.charAt(ai++) - '0') + (b.charAt(bi++) - '0');
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(aLen >= ai){
            int tmp = a.charAt(ai++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(bLen >= bi){
            int tmp = b.charAt(bi++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        if (ten != 0){
            str += ten;
        }
        return str;
    }

    public String alongMultiply(String s, char t){
        String ret = "";
        if (s.charAt(0) == '0' || t == '0'){
            return "0";
        }
        int tt = t - '0';
        int ten = 0;
        for (int i = s.length() - 1; i >= 0; i--){
            int tmp = s.charAt(i) - '0';
            tmp *= tt;
            tmp += ten;
            ten = tmp / 10;
            ret += tmp % 10;
        }
        if (ten != 0){
            ret += ten;
        }

        return ret;
    }
}

Explicación detallada: 

 Del título podemos obtener la siguiente información:

  1. El valor de entrada y el valor de retorno son ambos tipos de cadena;
  2. Los valores de entrada y los valores de retorno no se pueden convertir directamente a números enteros (porque los números son demasiado grandes);
  3. Casi no existen requisitos en cuanto a la complejidad del tiempo;
  4. La multiplicación negativa no ocurre.

 Una vez que comprendamos los requisitos del problema, debemos considerar cómo resolverlo.

 ¡Lo primero que debemos considerar es cómo se calcula la multiplicación !

Tomemos 11 * 99 como ejemplo:

Podemos analizar que la multiplicación de varios números se realiza según los siguientes pasos :

  1. Multiplica el primer número por cada dígito del segundo número;
  2. Si el primer número se multiplica por el dígito de las unidades del segundo número, se multiplica el resultado por uno, el dígito de las decenas por multiplicado por diez, y así sucesivamente;
  3. El último paso es sumar los resultados.

Después de llegar a este paso, si desea implementar estos contenidos en el método dado en la pregunta, aumentará enormemente la dificultad de escribir código. En este momento, recomiendo usar tres métodos para implementarlo.

  • La primera es la función principal, que se utiliza principalmente para implementar la idea general del código;
  • El segundo es el método de multiplicación, cuya función principal es multiplicar un número de n dígitos por un número de un solo dígito;
  • El tercero es el método de la suma, cuya función principal es sumar dos números de n dígitos.

Según la definición de multiplicación, podemos saber que 0 multiplicado por cualquier número es 0, por lo que nuestro primer código puede ser:

    public String solve (String s, String t) {
        // write code here
        if (s.charAt(0) == '0' || t.charAt(0) == '0'){
            return "0";
        }
    }

El siguiente paso es multiplicar cada dígito , pero no sabemos por cuántos dígitos se multiplica , por lo que en este momento debemos definir una matriz de cadenas tmp  basada en la longitud de t para almacenar cada dígito en t. El resultado de la multiplicación bits y s.

Luego defina un método llamado togetherMultiply(), que se utiliza para multiplicar números de n dígitos y números de un dígito y devolver el valor en forma de cadena . (Este método se puede implementar rápidamente).

Luego defina una variable denominada tipo de cadena e inicialícela en "0" para almacenar el valor de retorno final.

Debido a que habrá un acarreo, la cantidad de dígitos en el resultado final está llena de incertidumbre, por lo que podemos usar el método de almacenamiento de orden inverso. 

Es decir: 12345 se almacena como 54321

Debido a que la suma también tendrá un acarreo, podemos invertirla uniformemente al final del método principal.

 public String solve (String s, String t) {
        // write code here
        if (s.charAt(0) == '0' || t.charAt(0) == '0'){
            return "0";
        }
        String ret = "0";

        //新加的代码
        String[] tmp = new String[t.length()]; 
        for (int i = t.length() - 1; i >= 0; i--){
            tmp[i] = "";
            int j = t.length() - 1;
            while(j - i > 0){ //相当于十位乘十 , 百位乘一百……
                tmp[i] += '0';
                j--;
            }
            tmp[i] += alongMultiply(s, t.charAt(i));
        }
}

Luego agregamos todos los valores en la matriz tmp y los almacenamos en ret.

for (int i = t.length() - 1; i >= 0; i--){
            ret = Add(tmp[i], ret);
}

En este punto, nuestro diseño general se ha completado y es hora de implementar  el método togetherMultiply():

public String alongMultiply(String s, char t){
        String ret = ""; //用来存储最后的返回值
        if (s.charAt(0) == '0' || t == '0'){
            return "0";
        }
        int tt = t - '0';
        int ten = 0; //用来存储每次的进位
        for (int i = s.length() - 1; i >= 0; i--){
            int tmp = s.charAt(i) - '0';
            tmp *= tt;
            tmp += ten;
            ten = tmp / 10;
            ret += tmp % 10;
        }
        if (ten != 0){
            ret += ten;
        }

        return ret;
    }

 Implementación del método Add():

public String Add(String a, String b){
        String str = ""; //存储最终的返回值
        int aLen = a.length() - 1;
        int ai = 0;
        int bLen = b.length() - 1;
        int bi = 0;
        int ten = 0; //用来存储每次的进位

        while(aLen >= ai && bLen >= bi){
            int tmp = (a.charAt(ai++) - '0') + (b.charAt(bi++) - '0');
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(aLen >= ai){
            int tmp = a.charAt(ai++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        while(bLen >= bi){
            int tmp = b.charAt(bi++) - '0';
            tmp += ten;
            ten = tmp / 10;
            str += tmp % 10;
        }
        if (ten != 0){
            str += ten;
        }
        return str;
    }

A continuación, sólo necesitamos invertir el valor final para completar el problema:

        StringBuffer stringBuffer = new StringBuffer();
        for (int i = ret.length() - 1; i >= 0; i--){
            stringBuffer.append(ret.charAt(i));
        }
        ret = stringBuffer.toString();

 Por supuesto, también puedes usar (yo uso el método anterior principalmente porque es más rápido):

        tmp[0] = ret;
        ret = "";
        for (int i = tmp[0].length() - 1; i >= 0; i--){
            ret += tmp[0].charAt(i);
        }

Supongo que te gusta

Origin blog.csdn.net/2302_76339343/article/details/132737248
Recomendado
Clasificación