<LeetCode OJ> 204. Count Primes
Description:
Count the number of prime numbers less than a non-negative number, n.
思路首先:一个数不是合数就是素数,合数更好推断呢!
合数:不论什么一个合数都能够表现为适当个素数的乘积的形式,
所以我们仅仅用小于sqrt(number)的素数去除要推断的数就可以,
由于合数在sqrt(number)以内一定有素数的质因子
比方要推断100以内的素数,仅仅需推断合数就可以。仅仅用10以内的2,3。5。7就够了,10000以内的数用100以内的素数推断足以。执行时间O(N)
class Solution { public: int countPrimes(int n) { if(n<=2) return 0; basenum.reserve(10001);//预留空间 basenum.push_back(2); int cnt=1; for (int number=3; number < n; number++)//计算出n以内的素数个数 { int flag = true; int tmp = static_cast<int>(sqrt(number)); //推断是否是素数 int j = 0; while (basenum[j] <= tmp) { if (number % basenum[j] == 0) { //此时合数 flag = false; break; } j++; } if (flag) { basenum.push_back(number); cnt++; } } return cnt; } private: vector<int> basenum;//用于存储素数 };
这个问题是上海交通大学2008年的研究生面试题:
Prime Number
- 题目描写叙述:
-
Output the k-th prime number.
- 输入:
-
k≤10000
- 输出:
-
The k-th prime number.
- 例子输入:
-
3 7
- 例子输出:
-
5 17
#include "vector" #include <iostream> #include "fstream" #include "algorithm" #include <stdio.h> #include "string" #include <cmath> #include <cstdlib> #include "map" using namespace std; vector<int> basenum;//用于存储素数 //素数推断法:不论什么一个合数都能够表现为适当个素数的乘积的形式, //所以我们仅仅用小于sqrt(number)的素数去除要推断的数number就可以, //比方要推断100以内的素数。仅仅用10以内的2,3,5,7就够了,10000以内的数用100以内的素数推断足以。 void initPrime() { basenum.reserve(10001);//预留空间 basenum.push_back(2); basenum.push_back(3); basenum.push_back(5); basenum.push_back(7);//先压入4个素数 int number=11; for (int i = 5; i <= 10000; number++)//计算出10000个素数 { int flag = true; int tmp = static_cast<int>(sqrt(number)); //推断是否是素数 int j = 0; while (basenum[j] <= tmp) { if (number % basenum[j] == 0) { //此时合数 flag = false; break; } j++; } if (flag) { basenum.push_back(number); i++; } } } int main() { int n; initPrime(); while (cin>>n) printf("%d\n", basenum[n - 1]); return 0; } /************************************************************** Problem: 1040 User: EbowTang Language: C++ Result: Accepted Time:10 ms Memory:1536 kb ****************************************************************/
以前写过的最糟糕的素数推断方法:
//思路首先: //最朴素(糟糕)的方法 class Solution { public: bool IsPrimeNum(int num) { if (num <= 1) return false; for (int i = 2; i <= num/2; i++) { if (num % i == 0)//一旦能够整除立刻返回他不是素数 return false; } return true; } int countPrimes(int n) { int cnt=0; int curNum=1; while(curNum<=n) { if(IsPrimeNum(curNum)) cnt++; curNum++; } return cnt; } };
小结:遇到存在对立角度的问题,能够考虑用还有一面来破解,而不拘泥于正面破解。
以后素数问题都直接推断合数问题就可以。
注:本博文为EbowTang原创,兴许可能继续更新本文。
假设转载,请务必复制本条信息!
原文地址:http://blog.csdn.net/ebowtang/article/details/50469592
原作者博客:http://blog.csdn.net/ebowtang