[C++]判断质数

最近做了几个判断质数的函数,记录一下:

一·直接试除

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;
}

六·后记

效率:

猜你喜欢

转载自blog.csdn.net/szdytom/article/details/82913624