nowcoder NC10 大きな数の乗算

質問リンク:  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=unknown&judgeStat u s=未定義&タグ=&タイトル=

目次

トピックの説明:

答え:

詳細な説明: 


トピックの説明:

2 つの数値を文字列として読み取り、その積を計算して文字列として返す関数を作成します。

データ範囲:読み込んだ数値のサイズを満たす 0 \leqslant n \leqslant {10}^{1000}

要件:空間計算量 O(m)、時間計算量 O( m^{2}) (m が n の長さと仮定)

例 1:

入力:「11」、「99」

戻り値: "1089"

説明: 11*99=1089

例 2:

入力:「1」、「0」

戻り値: "0"

答え:

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

詳細な説明: 

 タイトルから次の情報が得られます。

  1. 入力値と戻り値は両方とも文字列型です。
  2. 入力値と戻り値を直接整数に変換することはできません (数値が大きすぎるため)。
  3. 時間計算量に関する要件はほとんどありません。
  4. 負の乗算は発生しません。

 問題の要件を理解した後、問題を解決する方法を検討する必要があります。

 最初に考慮すべきことは、乗算の計算方法です

例として 11 * 99 を考えてみましょう。

いくつかの数値の乗算が次の手順に従って実行されることを分析できます

  1. 最初の数値に 2 番目の数値の各桁を掛けます。
  2. 最初の数値に 2 番目の数値の一の位を乗算した場合、その結果に 1 を乗算し、10 の位の数値に 10 を乗算する、というようになります。
  3. 最後のステップは結果を合計することです。

ここまで来て、質問にあるような方法でこれらの内容を実装しようとすると、コードを書く難易度が大幅に上がってしまいますので、現時点では実際に3つの方法で実装することをお勧めします

  • 1 つ目は main 関数で、主にコードの全体的なアイデアを実装するために使用されます。
  • 2 番目は乗算方法で、その主な機能は n 桁の数値と 1 桁の数値を乗算することです。
  • 3 番目は加算法で、主な機能は 2 つの n 桁の数値を加算することです。

乗算の定義によれば、0 に任意の数値を乗算すると 0 になることがわかるため、最初のコードは次のようになります。

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

次のステップは、各桁を乗算することですが、何桁が乗算されるのかわかりません。そのため、この時点では、t の長さに基づいて文字列配列 tmp を定義し 、各桁を t に格納する必要があります。ビットとエス。

次に、longMultiply() という名前のメソッドを定義します。このメソッドは、n 桁の数値と 1 桁の数値を乗算し、その値を文字列の形式で返すために使用されます。(この方法は急いで実装できます)。

という名前の別の文字列型変数を定義し、それを「0」に初期化して、最終的な戻り値を格納します。

桁上げが発生するため、最終結果の桁数は不確実性が高くなりますので、逆順の格納方法を使用 できます。

つまり、12345 は 54321 として保存されます。

加算にはキャリーもあるので、メインメソッドの最後に反転を実行できます。

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

次に、tmp 配列内のすべての値を追加し、ret に保存します。

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

この時点で、全体的なレイアウトが完成したので、今度は、  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;
    }

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

次に、最終値を反転するだけで問題は完了します。

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

おすすめ

転載: blog.csdn.net/2302_76339343/article/details/132737248