博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【基本算法】统计n!尾部零
阅读量:2056 次
发布时间:2019-04-28

本文共 2094 字,大约阅读时间需要 6 分钟。

算法分析:

由于n的规模比较大,其尾数的个数也会相应地多,所以在这里我们可以用arr数组来存储阶乘的的各位数字,a[0]存储各位,a[1]存储十位,依次类推。

接下来还有个问题需要解决,那就是arr数组的个数。

在这里我们可以利用对数和来统计阶乘的个数m:

累加和: s = lg2 + lg3 + ...... + lgn

m = s + 1

然后设置循环进行累乘,将各个位数存入arr数组中。

i的结果依次为2、3、4、5、6、......、n

g为进位数

各个数的乘积t:

t = arr[j] * i + g;

乘积t的个位数字存于本数组

arr[j] = t %10

乘积t的十位以上数字作为进位数g,即余数

g = t /10

当把各个位数存入数组后,然后进行判断,如果为0,则零的个数count加一。

编程实现:

package cn.qblank.usual;import java.util.Scanner;/** * 统计n!尾数零 * @author Administrator * */public class Demo3 {	public static void main(String[] args) {		Scanner input = new Scanner(System.in);		System.out.println("请输入正整数n:(n<10000):");		int n = input.nextInt();		//统计零的个数		int count = 0;		//统计阶乘的总位数		double s = 0;		for(int i = 2;i <= n;i++){			s += Math.log10(i);		}		//求出总位数		int m = (int) (s + 1);		//创建数组		int[] arr = new int[m];		//初始化进位g=0,初始化数组第一位为1		int g = 0;		arr[0] = 1;		//进行阶乘		for (int i = 2; i <= n; i++) {			for (int j = 0; j < arr.length; j++) {				//算出每次的乘积 				int t = arr[j]*i + g;				//将每次乘积的个位数存入数组中 				arr[j] = t % 10;     				//将十位数作为进位数 				g = t / 10;			}		}		System.out.println("数组里面的值:");		//输出数组里面的值   本人亲测最多只能打印1053的阶乘值		for (int i = 0; i < arr.length; i++) {			System.out.print(arr[i]);		}				System.out.println();		System.out.println("长度" + arr.length);		//统计连续零的个数		while(arr[count] == 0){			count++;		}		System.out.println(n + "!尾数连续零的共有" + count + "个。");		input.close();			}}
运行结果:

由此可以看到,数组存储结果是反向存储的,这样方便计算零的个数

打印次数最多是以上结果,当超过以上值,则不能继续往下打印

当超过打印值时,则不打印,由此本次只讨论算法,所以就不在深入研究打印的问题。

算法优化:

通过实践,我们发现,以上的算法有点复杂。我们可以换个角度思考一下:既然要统计零的个数,而一个2的因子和5的因子就能产生一个零,那么我们可以直接通过统计2的因子和5的因子的个数来统计零的个数,但2的因子的个数要远远多于5的个数,于是我们就通过统计5的因子的个数.

5的因子的个数:count = [n/5] + [n/5*5] + *** + [n/5*..5]

编程实现:

package cn.qblank.usual;import java.util.Scanner;/** * 统计5的因子 * @author Administrator */public class Demo4 {	public static void main(String[] args) {		Scanner input = new Scanner(System.in);		System.out.println("请输入正整数n:");		int n = input.nextInt();		//统计个数		int count = 0;		//统计5		int t = 1;		//统计5的因子		while(t <= n){			t *= 5;			count += n/t;		}		System.out.println(n + "!零的个数是:" + count);		input.close();	}}

运行结果如下:

你可能感兴趣的文章
Git的Patch功能
查看>>
分析C语言的声明
查看>>
TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手
查看>>
C结构体、C++结构体、C++类的区别
查看>>
进程和线程的概念、区别和联系
查看>>
CMake 入门实战
查看>>
绑定CPU逻辑核心的利器——taskset
查看>>
Linux下perf性能测试火焰图只显示函数地址不显示函数名的问题
查看>>
c结构体、c++结构体和c++类的区别以及错误纠正
查看>>
Linux下查看根目录各文件内存占用情况
查看>>
A星算法详解(个人认为最详细,最通俗易懂的一个版本)
查看>>
利用栈实现DFS
查看>>
逆序对的数量(递归+归并思想)
查看>>
数的范围(二分查找上下界)
查看>>
算法导论阅读顺序
查看>>
Windows程序设计:直线绘制
查看>>
linux之CentOS下文件解压方式
查看>>
Django字段的创建并连接MYSQL
查看>>
div标签布局的使用
查看>>
HTML中表格的使用
查看>>