【JAVA】(vip)藍橋杯試題 基礎練習 高精度算法 BASIC-29 JAVA

試題 基礎練習 高精度加法

資源限制
時間限制:1.0s 內存限制:512.0MB

問題描述
  輸入兩個整數a和b,輸出這兩個整數的和。a和b都不超過100位。

算法描述
  由於a和b都比較大,所以不能直接使用語言中的標準數據類型來存儲。對於這種問題,一般使用數組來處理。
  定義一個數組A,A[0]用於存儲a的個位,A[1]用於存儲a的十位,依此類推。同樣可以用一個數組B來存儲b。
  計算c = a + b的時候,首先將A[0]與B[0]相加,如果有進位產生,則把進位(即和的十位數)存入r,把和的個位數存入C[0],即C[0]等於(A[0]+B[0])%10。然後計算A[1]與B[1]相加,這時還應將低位進上來的值r也加起來,即C[1]應該是A[1]、B[1]和r三個數的和.如果又有進位產生,則仍可將新的進位存入到r中,和的個位存到C[1]中。依此類推,即可求出C的所有位。
  最後將C輸出即可。

輸入格式
  輸入包括兩行,第一行爲一個非負整數a,第二行爲一個非負整數b。兩個整數都不超過100位,兩數的最高位都不是0。

輸出格式
  輸出一行,表示a + b的值。

樣例輸入
20100122201001221234567890
2010012220100122

樣例輸出
20100122203011233454668012

要點

  1. 三目算法

    java的三目算法

  2. JAVA中遍歷字符串中字符的方法

    JAVA中遍歷字符串中字符的三種方法

  3. JAVA爲什麼不建議在for循環中使用"+"進行字符串拼接,而是建議使用StringBuilder 的 append 方法?idea提示string concatenation ‘+=’in loop

    JAVA爲什麼不建議在for循環中使用"+"進行字符串拼接,而是建議使用StringBuilder 的 append 方法?idea提示string concatenation ‘+=’in loop

  4. 考慮幾個特殊值

    • 999+999
    • 999+9999

解題思路

總體上我都是按照題目給出的解題思路做的,具體實現思路有兩種,一種是比較A數組和B數組的長度(也就是a字符串和b字符串的長度),然後按長度分階段進行處理,另一種直接將比較短的數組變得和長的數組一樣長度,這樣就不用分階段了

這道題的解法其實題目中的算法描述已經說的很清楚了
算法描述
  由於a和b都比較大,所以不能直接使用語言中的標準數據類型來存儲。對於這種問題,一般使用數組來處理。
  定義一個數組A,A[0]用於存儲a的個位,A[1]用於存儲a的十位,依此類推。同樣可以用一個數組B來存儲b。
  計算c = a + b的時候,首先將A[0]與B[0]相加,如果有進位產生,則把進位(即和的十位數)存入r,把和的個位數存入C[0],即C[0]等於(A[0]+B[0])%10。然後計算A[1]與B[1]相加,這時還應將低位進上來的值r也加起來,即C[1]應該是A[1]、B[1]和r三個數的和.如果又有進位產生,則仍可將新的進位存入到r中,和的個位存到C[1]中。依此類推,即可求出C的所有位。
  最後將C輸出即可。

思路一:比較A、B數組長度大小,分階段處理

代碼

import java.util.ArrayList;
import java.util.Scanner;

public class HighPrecisionAddition4 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a = sc.next();
        String b = sc.next();
        sc.close();

        int[] A = reverse(a);
        int[] B = reverse(b);
//        System.out.println(Arrays.toString(A));
//        System.out.println(Arrays.toString(B));


        ArrayList C = add(A, B);
//         System.out.println(C);
        for (int i = C.size() - 1; i >= 0; i--) {
            System.out.print(C.get(i) + "");
        }
    }

    public static int[] reverse(String a) {
        char[] tmpA = a.toCharArray();
        int[] A = new int[a.length()];
        int index = 0;
        for (int i = a.length() - 1; i >= 0; i--) {
            A[index++] = tmpA[i] - '0';
        }

        return A;
    }

    public static ArrayList add(int[] A, int[] B) {
        int min;
        int max;
        boolean flag = true; //true爲表示A的長度大於B的長度
        if (A.length < B.length) {
            min = A.length;
            max = B.length;
            flag = false;
        } else if (A.length > B.length) {
            min = B.length;
            max = A.length;
        } else {
            min = max = A.length;
        }

        ArrayList<Integer> C = new ArrayList<Integer>();
        int r = 0;
        //A和B長度相同時進行的運算
        for (int i = 0; i < min; i++) {
            C.add((A[i] + B[i] + r) % 10);
            if (A[i] + B[i] + r < 10) {
                r = 0;
            } else {
                r = 1;
            }
        }

        //A和B長度相同,但是有999+999這種情況,會導致C長度不等於A和B的長度
        if (r == 1 && min == max) {
            C.add(1);
        }

        //當A和B長度不一致時,我們已經進行過長度一致部分的運算,現在進行剩餘的
        if (min != max) {
            for (int i = min; i < max; i++) {
                C.add((r + (flag ? A[i] : B[i])) % 10);
                if ((r + (flag ? A[i] : B[i])) < 10) {
                    r = 0;
                } else {
                    r = 1;
                    //可能會出現,999+9999這種情況。也是計算最後一位時,它又進位了,導致C長度變長
                    if (i == max - 1) {
                        C.add(1);
                    }
                }
            }
        }

        return C;
    }
}

思路二:將較短的數組的長度變得和較長數組的長度一樣

代碼

import java.util.ArrayList;
import java.util.Scanner;

public class HighPrecisionAddition5 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a = sc.next();
        String b = sc.next();
        sc.close();


        int max = Math.max(a.length(), b.length());

        int[] A = reverse(a, max);
        int[] B = reverse(b, max);
//        System.out.println(Arrays.toString(A));
//        System.out.println(Arrays.toString(B));
        ArrayList C = add(A, B);
//        System.out.println(C);
        for (int i = C.size() - 1; i >= 0; i--) {
            System.out.print(C.get(i) + "");
        }
    }

    public static int[] reverse(String a, int max) {
        char[] tmpA = a.toCharArray();
        int[] A = new int[max];
        int index = 0;
        for (int i = a.length() - 1; i >= 0; i--) {
            A[index++] = tmpA[i] - '0';
        }
        return A;
    }

    public static ArrayList add(int[] A, int[] B) {

        ArrayList<Integer> C = new ArrayList<Integer>();
        int r = 0;
        //A和B長度相同時進行的運算
        for (int i = 0; i < A.length; i++) {
            C.add((A[i] + B[i] + r) % 10);
            if (A[i] + B[i] + r < 10) {
                r = 0;
            } else {
                r = 1;
            }
        }

        //A和B長度相同,但是有999+999這種情況,會導致C長度不等於A和B的長度
        if (r == 1) {
            C.add(1);
        }

        /*//當A和B長度不一致時,我們已經進行過長度一致部分的運算,現在進行剩餘的
        if (min != max) {
            for (int i = min; i < max; i++) {
                C.add((r + (flag ? A[i] : B[i])) % 10);
                if ((r + (flag ? A[i] : B[i])) < 10) {
                    r = 0;
                } else {
                    r = 1;
                    //可能會出現,999+9999這種情況。也是計算最後一位時,它又進位了,導致C長度變長
                    if (i == max - 1) {
                        C.add(1);
                    }
                }
            }
        }*/
        return C;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章