素数
定义
素数又称作质数,是大于 1 且只能被 1 和 本身 整除的整数
合数是大于 1 且 不是 素数的数。
算法
第一种(判断)
通过定义及数学上的原理,判断出素数,为什么到sqrt(x),因为如果x是合数,它
拆分的两个因数一个 >= sqrt(x),一个<= sqrt(x),所以较小的因数的最大可能值就是sqrt(x)。
实现
bool isPrime(int x) {
bool prime = true;
if (x < 2) {
prime = false;
} else
for (int i = 2; i <= sqrt(x); i++) {
if (x % i == 0) {
prime = false;
break;
}
}
return prime;
}
第二种(选择)
利用素数表进行,通过它作为除数,对其他数进行整除判断。
原理
任何一个合数都可以分解为一个素数与另一个整数的乘积。 所以只要整数可以被(除自己以外)素数整除,必然是合数。
证明一下:对于任意一个合数n,它可以被分解为两个整数的乘积。分为两种情况:
- 俩都是合数
- 其中一个是素数
对于第二种情况,自然满足命题;
那么对于第一种情况,任取一个合数,又可以分解为两个因数,重复此步骤,要么存在素数,要么都是合数,每一次分解数的值在缩小,最后会要么得到素数,要么得到最小的合数4。而4可以分解成2 * 2,得到素数,自然命题成立。
实现
void selectSimple(int x) {
/* 初设几个素数 */
nums[0] = 2;
nums[1] = 3;
int count = 2;
if (x <= 1) {
count = 0;
} else if (x == 2 || x == 3) {
count = x - 1;
} else
for (int i = 4; i <= x; i++) {
/* 利用素数表判断 */
for (int j = 0; j < count; j++) {
if (i % nums[j] == 0) {
break;
}
/* 将素数加入素数表中 */
if (j == count - 1) {
nums[count] = i;
count++;
}
}
}
for (int i = 0; i < count; i++) {
std::cout << nums[i] << ' ';
}
}
第三种(选择)
前面介绍的基本是通过定义进行判断,现在介绍一种思想,排除筛查,就是通过已找出的素数(它们的倍数一定不是素数),排除一定范围内的合数,剩下的就是素数。
实现
/*收集0 ~ nums.size() - 1中的素数*/
void selectPrime(vector<int> &nums){
/*假定都是素数*/
for (int i = 0; i < nums.size(); i++) {
nums[i] = 1;
}
/*最小的素数2*/
for (int i = 2; i < nums.size(); i++) {
if (nums[i] == 1) {
/*从 i*i 开始,因为之前的素数将0 ~ i*i 的合数排除了*/
for (int j = i*i; j < nums.size(); j += i){
nums[j] = 0;
}
}
}
}
/* 输出素数 */
for (int i = 2; i < nums.size(); i++){
if (nums[i] == 1) {
cout << i << ' ';
}
}