【JAVA】(vip)藍橋杯試題 基礎練習 階乘計算 BASIC-30 JAVA

試題 基礎練習 階乘計算

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

問題描述
  輸入一個正整數n,輸出n!的值。
  其中n!=123*…*n。

算法描述
  n!可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。使用一個數組A來表示一個大整數a,A[0]表示a的個位,A[1]表示a的十位,依次類推。
  將a乘以一個整數k變爲將數組A的每一個元素都乘以k,請注意處理相應的進位。
  首先將a設爲1,然後乘2,乘3,當乘到n時,即得到了n!的值。

輸入格式
  輸入包含一個正整數n,n<=1000。

輸出格式
  輸出n!的準確值。

樣例輸入
10

樣例輸出
3628800

要點

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

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

思路

題目給出的算法描述就很好,按這個做就行,代碼其實沒多少,就是很繞,需要靜下心好好想想
算法描述
  n!可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。使用一個數組A來表示一個大整數a,A[0]表示a的個位,A[1]表示a的十位,依次類推。
  將a乘以一個整數k變爲將數組A的每一個元素都乘以k,請注意處理相應的進位。
  首先將a設爲1,然後乘2,乘3,當乘到n時,即得到了n!的值。

代碼(無註釋)

爲了讓你們看到代碼有多麼少,所以專門把註釋刪了

import java.util.ArrayList;
import java.util.Scanner;
public class FactorialCalculation2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.close();

        ArrayList A = calculating(n);
        StringBuilder str = new StringBuilder();
        for (int i = A.size() - 1; i >= 0; i--) {
            str.append(A.get(i));
        }
        System.out.print(str);
    }

    public static ArrayList calculating(int n) {
        ArrayList<Integer> A = new ArrayList<Integer>();
        A.add(1);//首先將a設爲1
        int highest = 1;//最高位數,比如999的最高位數爲3
        for (int i = 2; i <= n; i++) {
            int carry = 0; //進位數,比如9+9,進位數爲1
            int temp;
            for (int j = 0; j < highest; j++) {
                temp = A.get(j) * i + carry;
                A.set(j, temp % 10);
                carry = temp / 10;
            }
            while (carry != 0) {
                A.add(carry % 10);
                carry = carry / 10;
                highest++;
            }
        }
        return A;
    }
}

代碼(含有註釋)

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

public class FactorialCalculation {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.close();

        ArrayList A = calculating(n);
        StringBuilder str = new StringBuilder();
        for (int i = A.size() - 1; i >= 0; i--) {
            str.append(A.get(i));
        }
        System.out.print(str);
    }

    public static ArrayList calculating(int n) {
        ArrayList<Integer> A = new ArrayList<Integer>();
        A.add(1);//首先將a設爲1
        int highest = 1;//最高位數,比如999的最高位數爲3
        for (int i = 2; i <= n; i++) {
            int carry = 0; //進位數,比如9+9,進位數爲1
            int temp;
            for (int j = 0; j < highest; j++) {
                // 題目算法描述中說,將a乘以一個整數k變爲將數組A的每一個元素都乘以k
                // A.get(j)是A數組位置爲j的原有的數,你在乘以i之後,需要加上下一位的進位carry
                // 比如十位乘以i之後,得加上個位乘以i的進位
                // 例如987*3=2961,A=【7,8,9】,A.get(1)爲位置爲1的原有的數,它乘以3之後,需要加上7乘以3的進位2
                temp = A.get(j) * i + carry;
                // 取餘數覆蓋A數組中位置爲j的元素
                // 例如987*3=2961,個位7乘以3之後,將1變爲A數組新的個位,也就是覆蓋0位置
                A.set(j, temp % 10);
                // 進位
                // 例如987*3=2961,個位7乘以3之後,進位carry爲2
                carry = temp / 10;
            }
            // 當位數增加時,比如999*3=2997,它的最高位數就從3變成4,A數組就得增加新元素,長度增加
            while (carry != 0) {
                // 以999*3=2997爲例,這裏carry等於2,如果你奇怪這裏爲啥取餘,
                // 那你想999*99=98901,這裏的carry=98
                A.add(carry % 10);
                // 位數可能不只是增加了1,可能大於1,比如這裏進位carry=98,
                // 位數就在999三位的基礎上增加了兩位,所以你得對carry進行整除,
                // 98/10等於9  8已經增加到A數組中了,9在下一次循環增加到A數組中
                carry = carry / 10;
                // 更新最高位數
                highest++;
            }
        }
        return A;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章