最近做了几个判断质数的函数,记录一下:
一·直接试除
bool is_prime3(unsigned long long n) { //slow
for (int i = 2; i < n - 1; i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
note:比较慢
二·一点优化
每次试除时其实只要除到 sqrt(n)
并且除2之外不需要试除偶数
bool is_prime2(unsigned long long n) { //middle
long long stop = sqrt(n) + 1;
if (n == 2) {
return 1;
}
if (n % 2 == 0) {
return 0;
}
for (int i = 3; i <= stop; i += 2) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
三·6n ± 1
如果 n 是一个质数(不为2或3), 那么:
n = 6n ± 1
因为如果 n 是一个质数(不为2或3)那么 n % 2 != 0 且 n % 3 != 0
bool is_prime(unsigned long long n) { //quick
unsigned long long stop = n / 6 + 1, Tstop = sqrt(n) + 5;
if (n == 2 || n == 3 || n == 5 || n == 7 || n == 11) {
return 1;
}
if (n % 2 == 0 || n % 3 == 0 || n % 5 == 0) {
return 0;
}
for (unsigned long long i = 1; i <= stop; i++) {
if (i * 6 >= Tstop) {break;}
if ((n % (i * 6 + 1) == 0) || (n % (i * 6 + 5) == 0)) {
return 0;
}
}
return 1;
}
四·测试
编写一个main()函数来测试一下:
int main() {
unsigned long long n;
int flag;
clock_t start, end;
while (true) {
cout << "number: " << flush;
cin >> n;
cout << n << endl;
bool tmp;
start = clock();
flag = is_prime3(n);
end = clock();
cout << flag << "\t" << end - start << "ms\n";
start = clock();
tmp = is_prime2(n);
end = clock();
if (tmp != flag) {
flag = -1;
}
cout << tmp << "\t" << end - start << "ms\n";
start = clock();
tmp = is_prime(n);
end = clock();
if (tmp != flag) {
flag = -1;
}
cout << tmp << "\t" << end - start << "ms\n";
switch(flag) {
case -1:
cout << "UNKNOW" << endl;
break;
case 0:
cout << "NON-PRIME" << endl;
break;
case 1:
cout << "PRIME" << endl;
}
}
return 0;
}
五·完整代码:
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;
bool is_prime3(unsigned long long n) { //slow
for (int i = 2; i < n - 1; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
bool is_prime2(unsigned long long n) { //unknow
long long stop = sqrt(n) + 1;
if (n == 2) {
return true;
}
if (n % 2 == 0) {
return false;
}
for (int i = 3; i <= stop; i += 2) {
if (n % i == 0) {
return false;
}
}
return true;
}
bool is_prime(unsigned long long n) { //unknow
long long stop = n / 6 + 1, Tstop = sqrt(n) + 5;
if (n == 2 || n == 3 || n == 5) {
return true;
}
if (n % 2 == 0 || n % 3 == 0 || n % 5 == 0) {
return false;
}
for (int i = 1; i <= stop; i++) {
if (i * 6 >= Tstop) {break;}
//cout << i*6+1 << " " << i*6+5 << endl;
if ((n % (i * 6 + 1) == 0) || (n % (i * 6 + 5) == 0)) {
return false;
}
}
return true;
}
int main() {
unsigned long long n;
int flag;
clock_t start, end;
while (true) {
cout << "number: " << flush;
cin >> n;
cout << n << endl;
bool tmp;
start = clock();
flag = is_prime3(n);
end = clock();
cout << flag << "\t" << end - start << "ms\n";
start = clock();
tmp = is_prime2(n);
end = clock();
if (tmp != flag) {
flag = -1;
}
cout << tmp << "\t" << end - start << "ms\n";
start = clock();
tmp = is_prime(n);
end = clock();
if (tmp != flag) {
flag = -1;
}
cout << tmp << "\t" << end - start << "ms\n";
switch(flag) {
case -1:
cout << "UNKNOW" << endl;
break;
case 0:
cout << "NON-PRIME" << endl;
break;
case 1:
cout << "PRIME" << endl;
}
}
return 0;
}
六·后记
效率: