Description:html
Count the number of prime numbers less than a non-negative number, n.ios
思路首先:一個數不是合數就是素數,合數更好推斷呢!面試
合數:不論什麼一個合數都可以表現爲適當個素數的乘積的形式,
因此咱們僅僅用小於sqrt(number)的素數去除要推斷的數就能夠,
因爲合數在sqrt(number)之內必定有素數的質因子
比方要推斷100之內的素數,僅僅需推斷合數就能夠。僅僅用10之內的2,3。5。7就夠了,10000之內的數用100之內的素數推斷足以。執行時間O(N)
less
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年的研究生面試題:spa
Prime Number.net
Output the k-th prime number.code
k≤10000htm
The k-th prime number.blog
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 ****************************************************************/
之前寫過的最糟糕的素數推斷方法:ip
//思路首先: //最樸素(糟糕)的方法 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