我感觉素数这一块也是比较重要的,尤其是在密码学、网络安全、身份验证等这一块。素数(也叫质数)是我们在小学?或者初中吧···学到的一个数学名词,含义是“只能被1和本身整除”。因此,这个概念可以被用来判断一个数字是不是素数,或者打印素数。(并且我们知道小于2的数字,都不是素数)
#include <iostream>
#include <iso646.h>
#include <algorithm>
#include <functional>
// 素性测试
bool isPrimer(int number) {
if ( number <2 ) return false;
for (size_t i = 2; i < number; i++) {
if (number % 2 == 0) {
return false;
}
}
return true;
}
int main() {
int M;
std::cin >> M;
std::cout << std::boolalpha << isPrimer(M) << std::endl;
std::cin.get();
}
我们继续来看:假设有一个数是a,那么a = pow(a,1/2) * pow(a,1/2); 如果a非素,那么一定有一个数字是小于pow(a,1/2)的,因此,只需要遍历到sqrt(a)即可。
#include <iostream>
#include <iso646.h>
#include <algorithm>
#include <functional>
// 素性测试
bool isPrimer(int number) {
if ( number <2 ) return false;
for (size_t i = 2; i < sqrt(number); i++) {
if (number % 2 == 0) {
return false;
}
}
return true;
}
int main() {
int M;
std::cin >> M;
std::cout << std::boolalpha << isPrimer(M) << std::endl;
std::cin.get();
}
你看这个就是素数的检测,但是我们还有其他的办法吗?有的,打表。看下边的动态图:
注意观察,他是从2开始,将2的倍数都标记为非素数,然后从3开始,将3的倍数都标记为非素数,然后从5开始,将5的倍数都标记为非素数···,规律就是,一开始的时候,将开辟的数组都预初始化为true,然后开始从2遍历,一直到n,在循环体内,然后再次通过循环,将基础素数的倍数都标记为false,那剩余的就是true,就是素数。
#include <iostream>
#include <iso646.h>
#include <algorithm>
#include <functional>
// 素数打表
void PrimerArray(int number) {
if (number < 2) std::cout << "No Primer" << std::endl;
bool *isPrimer = new bool[number];
isPrimer[0] = isPrimer[1] = false;
memset(isPrimer + 2, true, number);
for (size_t i = 2; i < number; i++) {
if (isPrimer) {
for (size_t ii = i + i; ii < number; ii += i) {
isPrimer[ii] = false;
}
}
}
for (size_t i = 0; i < number; i++) {
if (isPrimer[i]) {
std::cout << i << std::endl;
}
}
}
// 素数判断
bool isPrimer(int number) {
if (number < 2) std::cout << "No Primer" << std::endl;
bool *isPrimer = new bool[number];
isPrimer[0] = isPrimer[1] = false;
memset(isPrimer + 2, true, number);
for (size_t i = 2; i < number; i++) {
if (isPrimer) {
for (size_t ii = i + i; ii < number; ii += i) {
isPrimer[ii] = false;
}
}
}
return isPrimer[number];
}
int main() {
int M;
std::cin >> M;
// 素数打表
PrimerArray(M);
// 素性测试
isPrimer(M);
std::cin.get();
}
但是你看,依然有优化的空间,原理和之前的一样。
#include <iostream>
#include <iso646.h>
#include <algorithm>
#include <functional>
// 素数打表
void PrimerArray(int number) {
if (number < 2) std::cout << "No Primer" << std::endl;
bool *isPrimer = new bool[number];
isPrimer[0] = isPrimer[1] = false;
memset(isPrimer + 2, true, number);
for (size_t i = 2; i < sqrt(number); i++) {
if (isPrimer) {
for (size_t ii = i + i; ii < number; ii += i) {
isPrimer[ii] = false;
}
}
}
for (size_t i = 0; i < number; i++) {
if (isPrimer[i]) {
std::cout << i << std::endl;
}
}
}
// 素数判断
bool isPrimer(int number) {
if (number < 2) std::cout << "No Primer" << std::endl;
bool *isPrimer = new bool[number];
isPrimer[0] = isPrimer[1] = false;
memset(isPrimer + 2, true, number);
for (size_t i = 2; i < sqrt(number); i++) {
if (isPrimer) {
for (size_t ii = i + i; ii < number; ii += i) {
isPrimer[ii] = false;
}
}
}
return isPrimer[number];
}
int main() {
int M;
std::cin >> M;
// 素数打表
PrimerArray(M);
// 素性测试
isPrimer(M);
std::cin.get();
}
现在来看,“埃拉托斯特尼筛法”就完成了,但是还是有优化的空间,随后我再继续优化。素数在日常中其实用处也是很广泛的,我们需要注意观察一些数学知识在生活中的应用,多交流与学习,善于观察细节、才能学到更多的有用的知识了。
这个是我的关于素数(http://blog.youkuaiyun.com/u010202481/article/details/78063861)的其他的内容,大家可以相互探讨,不吝赐教。