nowcoder NC10 Multiplicação de números grandes

Link do tópico:  icon-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=undefined&judgeS tatu s=indefinido&tags=&title=

Índice

Descrição do tópico:

Responder:

Explicação detalhada: 


Descrição do tópico:

Leia dois números como strings, escreva uma função para calcular seu produto e retorne-o como uma string.

Intervalo de dados: o tamanho do número lido satisfaz 0 \leqslant n \leqslant {10}^{1000}

Requisitos: Complexidade espacial O(m), complexidade de tempo O( m^{2}) (assumindo que m é o comprimento de n)

Exemplo 1:

Entrada: "11","99"

Valor de retorno: "1089"

Descrição: 11*99=1089

Exemplo 2:

Entrada: "1","0"

Valor de retorno: "0"

Responder:

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

Explicação detalhada: 

 Do título podemos obter as seguintes informações:

  1. O valor de entrada e o valor de retorno são tipos de string;
  2. Os valores de entrada e os valores de retorno não podem ser convertidos diretamente em números inteiros (porque os números são muito grandes);
  3. Quase não há requisitos quanto à complexidade do tempo;
  4. A multiplicação negativa não ocorre.

 Depois de entendermos os requisitos do problema, devemos considerar como resolvê-lo.

 A primeira coisa que devemos considerar é como a multiplicação é calculada !

Tomemos 11 * 99 como exemplo:

Podemos analisar que a multiplicação de vários números é realizada de acordo com os seguintes passos :

  1. Multiplique o primeiro número por cada dígito do segundo número;
  2. Se o primeiro número for multiplicado pelo dígito das unidades do segundo número, multiplique o resultado por um, o dígito das dezenas por multiplicado por dez e assim por diante;
  3. A etapa final é somar os resultados.

Após esta etapa, se você quiser implementar esse conteúdo no método indicado no título, a dificuldade de escrever código aumentará muito. Neste momento, na verdade, recomendo usar três métodos para implementá-lo.

  • A primeira é a função principal, que serve principalmente para implementar a ideia geral do código;
  • O segundo é o método de multiplicação, cuja principal função é multiplicar um número de n dígitos por um número de um único dígito;
  • O terceiro é o método de adição, cuja principal função é somar dois números de n dígitos.

De acordo com a definição de multiplicação, podemos saber que 0 multiplicado por qualquer número é 0, então nosso primeiro trecho de código pode ser:

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

A próxima etapa é multiplicar cada dígito , mas não sabemos quantos dígitos são multiplicados por quantos dígitos , então devemos definir uma matriz de strings tmp  de acordo com o comprimento de t para armazenar cada um dos t O resultado da multiplicação de bits e S.

Em seguida, defina um método chamado alongMultiply(). Este método é usado para multiplicar números de n dígitos e números de um dígito e retornar o valor na forma de uma string . (Este método pode ser implementado rapidamente).

Defina outra variável de tipo string chamada e inicialize-a com "0" para armazenar o valor de retorno final.

Como haverá um carry, o número de dígitos no resultado final está cheio de incertezas, então podemos usar o método de armazenamento em ordem inversa. 

Ou seja: 12345 é armazenado como 54321

Como a adição também terá um carry, podemos realizar a reversão no final do 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));
        }
}

Em seguida, adicionamos todos os valores no array tmp e os armazenamos em ret.

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

Neste ponto, nosso layout geral foi concluído e agora é hora de implementar  o método alongMultiply():

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

 Implementação do 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 seguir, basta inverter o valor final e o problema está concluído:

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

 Claro que você também pode usar (eu uso o método acima principalmente porque é mais rápido):

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

Acho que você gosta

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