試題 基礎練習 階乘計算
資源限制
時間限制: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
要點
-
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;
}
}