素数判断
判断素数还是很简单的,两种写法
bool isPrime(int n){
if(n<=1) return false;
int sqr = (int)sqrt(1.0 * n);//因为sqrt是浮点型开根号.
for(int i = 2;i<=sqr;i++){
if(n%i==0) return false;
}
return true;
}
for循环里面必须带等号,必须带.
这种是带了开根号,也可以不开根号,for循环里面那就是
| |
n在10^9以内是安全的.
遍历素数
有了上面的判断素数的方法,似乎遍历素数也很容易,直接循环判断就好了.
不过,这样并不是最优解,时间复杂度还是有优化的空间的.
再说一种方法:”埃式筛法”
因为这个简单,容易理解,时间复杂度是O(nloglogn),欧拉筛法可以达到O(n),不介绍了,先说这个.
埃式筛法原理: 对每一个素数,筛去他的所有倍数
比如打印0~100以内的素数,先确定2是素数,然后筛去2所有的倍数,然后依次向后,3没有被它前面的数筛掉,所以3一定是素数,然后再筛3的倍数,依次是4,因为被2筛掉,所以不是质数….
#include<iostream>
using namespace std;
const int maxn = 101;
int prime[maxn], pNum = 0;
bool p[maxn] = { 0 };
void Find_Prime(){
for (int i = 2; i < maxn; i++){
if (p[i] == false){
prime[pNum++] = i;
for (int j = i + i; j < maxn; j += i){
p[j] = true;
}
}
}
}
int main(){
Find_Prime();
for (int i = 0; i < pNum; i++)
cout << prime[i] << endl;
return 0;
}
质因子分解
| |
所以180质因子分解就是 2 3 5,在程序中怎么存储呢?
定义一个结构体factor存储:
struct factor{
int x,cnt;//x是质因子,cnt是个数.
}fac[10];//10个长度够用了,因为
//2*3*5*7*11*13*17*19*23*29的乘积已经超过int的范围了.
刚才判断质数的第一种写法,是有着原理的,还是说一下吧:
对于一个数n,如果他有除了1和它本身之外的因子,那么应该分布在sqrt(n)的两侧成对出现.
现在这个结论对求质因子来说,同样适用,可以做延伸.
如果一个数n是又质因子乘积构成 ,那么质因子要么全都在sqrt(n)左侧,要么只有一个出现在sqrt(n)的右边
如此,便可以用这个来求解质因子了…
上面的prime[]数组里面存放的数组,代码就不在重复了,实现一下逻辑.
if(n%prime[i] == 0){//也就是说prime[i]是n的因子
fac[num].x=prime[i];//记录该因子
fac[num].cnt = 0;
while(n%prime[i]==0){//计算质因子prime[i]的个数
fac[num].cnt++;
n /= prime[i];
}
num++;//不同质因子个数加1
}
如果上面的步骤结束后n还大于1,说明有一个大于sqrt(n)的质因子(有可能是n本身),这是需要把质因子加入fac数组,并令其个数为1.
if(n != 1){
fac[num].x = n;
fac[num++].cnt = 1;
}
至此,fac数组中存放的就是质因子分解的结果.
参考:<<算法笔记>>