本帖最后由 hejinzhong 于 2014-8-1 01:06 编辑
* (1)由于1000!的结果太大,无法直接用一个基本数据类型的变量来存储,所以定义一个数组来分别存计算结果的每一位数字。
* (2)计算过程:让每个角标上的数字和相应的乘数相乘并加上前一位的进位。(细节参看 下面calculator 函数)
* (3)遍历数组,查询0的个数。
*
* 举个例子说明计算过程
* 3024 x 15 = 45360(计算器计算结果)
* 每次开始计算进位都为0
* 角标 元素 乘数 上位进位 运算后该角标值 该位产生的进位
* 0 4 x 15 + 0 = 60 0 6
* 1 2 x 15 + 6 = 36 6 3
* 2 0 x 15 + 3 = 03 3 0
* 3 3 x 15 + 0 = 45 5 4//3024已经算完了,还有进位,多算3位
* 4 0 x 15 + 4 = 04 4 0
* 5 0 x 15 + 0 = 00 0 0
* 6 0 x 15 + 0 = 00 0 0
* 这样在数组中的元素倒着看即为 0045360,当去掉前面0,即为我们需要的运算结果。
*
- public class Test9
- {
- private static final int MAX_BOUNDS = 3000;//当角标越界时,可调大该数值
-
- public static void main(String[] args)
- {
- factorial(1000);//求1000的阶乘
- }
-
- public static void factorial(int num)
- {
- int[] arr = new int[MAX_BOUNDS];
- calculator(arr,num);//计算num的阶乘
- checkZero(arr);//统计结果中0的个数
- }
-
- private static int[] calculator(int[] arr,int num)
- {
- arr[0]=1;//将数组中0位元素设为1,任何数和1相乘不影响结果.
-
- for(int i=1;i<=num;i++)
- {
- int temp = 0,carry = 0;
- int max = max(arr);
-
- for(int j=0;j<max+4;j++)//乘以1000以内的数,增加的长度不超过3,多向后检测3位。
- {
- temp=arr[j]*i+carry;
- arr[j]=temp%10;//当前角标值
- carry=temp/10;//进位
- }
- }
- return arr;
- }
-
- private static void checkZero(int[] arr)//检测数组中一共有多少个0,最高位开始
- {
- int count = 0;
- for(int i=max(arr);i>=0;i--)
- {
- if(arr[i]==0)
- count++;
- }
- System.out.println("共包含0个数:"+count);
- }
-
- private static int max(int[] arr)//检测数组中非0的最大角标
- {
- for(int max= MAX_BOUNDS-1;max>0;max--)
- {
- while(arr[max]!=0)
- return max;
- }
- return 0;
- }
- }
复制代码 |
|