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.youkuaiyun.com/ebowtang/article/details/50469592
原作者博客:http://blog.youkuaiyun.com/ebowtang