进行小数字的阶乘计算一般是使用递归方法来实现,比如计算5的阶乘:
public static void main(String[] args) {
System.out.println(method_factorial(5));
}
public static long method_factorial(long number){
if(number == 0 || number == 1){
return 1;
}else{
return (number * method_factorial(number - 1));
}
}
但是当进行大数字的阶乘计算时,显然不能使用递归算法,因为数据太大,没有合适的数据类型进行存储,比如100!
此时使用的方法是用数组来模拟数字,数组的一位对应数字的一位
其核心思想是:
用数组来存放阶乘的每一位数字,首先令第一位的数值为1,位数为1,然后将每次相乘的乘积存回数组,并循环处理每个数组中超过10的数,若数值超过10,则需要进位,将位数加1,原来的数除以10,商数加前一位数的数值后存回前一位数的数组中,再将余数存回原来位数的数组中。
方法实现:
public class Factorial {
//初始一个数组,要比较大,符合预期所需要的大小
private static int[] resultArray = new int[10000];
//进位,在计算时进行进位操作
static int resultCarry= 0;
//模拟数字的进位,数组的低地址表示数据的地位,依次类推,初始时从低位进行计算
static long index = 0;
public static void main(String[] args) {
System.out.println("请输入所求阶乘的N的值:");
Scanner scanner_in= new Scanner(System.in);
int number =scanner_in.nextInt();
long maxIndex = method(number);
System.out.println("阶乘为:");
for (long i = maxIndex-1; i >= 0; i--) {
System.out.print(resultArray[(int) i]);
}
}
//方法返回值应为数组的实际使用长度,不应该是返回整个数组数据
//因为不会用完数组所有的位,未用到的位全部是0,所以输出没有意义
//0020虽然能算是20,但是千分位和百分位的0并没有意义,所以此处只要得到数组真正使用了多少位并将真正有意义的位输出即可
//或者返回整个数组数据,同时应返回数组实际使用长度
public static long method(long number) {
//使用长度
long maxIndex = 1;
int temp = 0;
resultArray[0] = 1;
for (long i = 1; i <= number; i++) {
for (long j = 0; j < maxIndex; j++) {
resultArray[(int) j] *= i;
resultArray[(int) j] +=resultCarry;
temp = resultArray[(int) j];
if (temp >= 10) {
resultArray[(int) index] = temp % 10;
resultCarry= temp / 10;
index++;
if(maxIndex<index+1)
maxIndex = index+1;
} else {
index++;
resultCarry= 0;
}
}
index = 0;
}
return maxIndex;
}
}