本帖最后由 jackz007 于 2024-3-4 23:06 编辑
要判定一个数 M 是否是素数,一般需要用 M 去除以 2 ~ M - 1 之间所有的数,看看是否能找到某一个整除因子来进行判定,比如,要判定 12 是否是素数,那就需要用 12 分别去除以 2、3、4、5、6、7、8、9、10、11,我们知道,乘法满足交换律,如果 M = a x b,那么,a 和 b 都是 M 的因子,这就意味着 M % a = 0,M % b = 0,什么意思呢? 12 = 2 x 6
12 = 3 x 4
12 = 4 x 3
12 = 6 x 2
在 2 ~ 11 的范围内,12 的因子的确有 2、3、4、6,但是,很显然,我们只需要判断一半,也就是判断 12 % 2 以及 12 % 3 就等于同时判断了后两个因子 12 % 4 和 12 % 6。而这个前后分界线,就是 sqrt(12) = 3,就是说,为了判定 12 是否是素数,我们只需要判定 12 % 2、12 % 3 就足够了,无需再判断后面的 4、5、6、7、8、9、10、11,当然,12 不是素数,本身也无需做完所有的因子判定即可以有结果,但是,如果目标数是一个素数,那就会有意义了,那将使运算效率大幅度提高。
在本例的代码中,q = sqrt(m) 就是因子分界线,代码逻辑是,如果枚举因子到了 k >= q + 1 都没能找到任何一个因子,那么,无需继续枚举,完全可以断言,m 必然就是一个素数。
我也提供一个参考代码: #include<stdio.h>
int main(void)
{
int k , m , n ;
for(m = 100 , n = 0 ; m < 201 ; m ++) {
for(k = 2 ; k * k < m + 1 && m % k ; k ++) ;
if(k * k >= m + 1) { // 如果关于 k 的循环不是因为 m % k = 0 而结束
printf("%3d\t" , m) ; // 那么,m 就是一个素数无疑。
n ++ ;
if(n % 6 == 0) printf("\n") ;
}
}
}
编译、运行实况:D:\[exercise]\C>g++ -o x x.c
D:\[exercise]\C>x
101 103 107 109 113 127
131 137 139 149 151 157
163 167 173 179 181 191
193 197 199
D:\[exercise]\C>
|