Java语法实例分析
导读:本文共4259字符,通常情况下阅读需要14分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 一,素数求解的n种境界1.1,暴力循环求解publicclassTestDemo220427{publicstaticvoidmain(String[]args){//这里以求取1~100之间的素数为例for(inti=2;i<=100;i++){//素数从2开始,所以从2开始产生到100的数intflg=1;//假设是素数for(intj=2;... ...
目录
(为您整理了一些要点),点击可以直达。可以发现,我们一个数都是可以拆成两个数的乘法的,比如 16:可以是 1 16,2 * 8,4*4,可以看到,前半部分的数都是小于其自身的一半的,所以我们只需要检测这前半部分数能否被其自身整除了,因为只要前半部分有的话,后半部分肯定有一个数与之对应相乘能够得到自身,所以这就又减少了一半的工作量。*
还是刚才差不多的原理,只不过把范围又缩小了,因为一个数拆分成两个数的乘积的形式的话,前面的那个数不仅仅只是小于其自身的一半,其实根本上是不可能大于其开平方的值的,就比如16,其实前半部分的数不会大于4,因为大于4后可以看到不可能会有某个数能够与另一个数乘了等于16了,当然2 * 8,8 * 2这只算前面一种就好了
我们知道,除了2这个特例,所有的偶数不可能是素数,因为最起码就能够被2整除,所以在范围内进行考虑的时候,就只需要检测奇数就好了,就把外层循环的次数减少了。
其实还有方法可以继续优化,这里就不再给大家一一列举了,如果大家有兴趣的话可以去查查,很多博主写的很详细深入!
这里就只需要知道闰年的判断标准就可以很好的把题解出来。
其实还有一个公式,假设最大公约数是m,则最小公倍数是 (a*b)/m。
注意:这段代码是有bug的,因为对于负数是统计不了的,负数的二进制最高符号位为1,右移补符号位那就是一直在高位补1,那循环就死循环了。
解决方法:num = num >> 1 ——> 改成 num = num >>> 1,用无符号右移,这样高位就只会补0,对于正数负数都适用。
拓展:可能有人会问,既然可以右移,那为啥不能左移?
答案是 : 确实可以左移,但是不推荐,效率太低。
这个时候就不是把这个数去左移了,而是把1左移,然后去与这个数按位与,因为这样的结果就只有可能是0或者非0,非0就表示1左移后的结果的1所在的位置对应的这个数的位置上是1,所以这个时候就统计一下。这样也可以解决问题,但是你必须得左移32次,因为你不知道这个数前面到底有多少1,只能所有的都比对完。
这种方法正数负数都可以用,并且效率很高,每次按位与num-1 一次,就会消掉一个1。
扩展:用这个方法判断某一个数是不是2的k次方。
Java语法实例分析的详细内容,希望对您有所帮助,信息来源于网络。