Índice
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
Requisitos: Complexidade espacial O(m), complexidade de tempo O( ) (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:
- O valor de entrada e o valor de retorno são tipos de string;
- 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);
- Quase não há requisitos quanto à complexidade do tempo;
- 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 :
- Multiplique o primeiro número por cada dígito do segundo número;
- 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;
- 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);
}