判断质数
普通方法
private boolean isPrime(int x) {
if (x < 2) {
return false;
}
for (int i = 2; i * i <= x; ++i) {
if (x % i == 0) {
return false;
}
}
return true;
}
巧妙的方法:
今天做的这个题有点特殊,该题中出现的质数绝对不会超过20,而不超过20的质数只有:2,3,5,7,11,13,17,19。
可以用一个 m a s k = 665772 = 1010001010001010110 0 2 mask=665772=10100010100010101100_2 mask=665772=101000101000101011002来存储这些质数,其中mask 二进制的从低到高的第 i 位为 1 表示 i 是质数,为 0 表示 i 不是质数。
设整数 x 的二进制中 1 的个数为 c,若mask 按位与 2 c 2^c 2c不为 0,则说明 c 是一个质数。
2
c
2^c
2c可以用1 << Integer.bitCount(x)
表示,此时,若((1 << Integer.bitCount(x)) & 665772) != 0
则c为质数。
整数x的二进制表示有多少位1
java库函数
Integer.bitCount(x)
x&=x-1
x&=x-1可以消除x最低位的1,while循环计数,直到x=0即可。
x的最低位一定是/1[0]*/。如果x的低位是10000
,则x-1的低位是01111
,x&=x-1则可以消除掉最低位的1。如此循环,直到x=0,则可以统计出x的二进制表示中1的位数
lowbit
举个例子:
l
o
w
b
i
t
(
6
)
=
2
lowbit(6)=2
lowbit(6)=2,lowbit运算就是x&=-x,这样运算完后,只会保留x最低位的1。
例如,x为1000 1010
,则-x为0111 0110
。
注意,计算机中负数的表示方法是取反+1
。
x-- 1000 1010
x取反- 0111 0101
再+1-- 0111 0110
x&-x只会保留x最低位的1。这种方式的原理其实和x&=x-1有异曲同工之妙。
x的低位一定是10000
这样的形式,则x取反的低位是01111
,x取反+1的低位是10000
。所以x和-x的最低位的1以及之后的所有位都是相等的,而之前的位都是相反的,所以两者按位与只会保留最低位的1。