素数判断问题

素数判断

判断素数还是很简单的,两种写法

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循环里面那就是

1
for(int i= 2;i*i<=n;i++)

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

质因子分解

1
180=2*2*3*3*5

所以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数组中存放的就是质因子分解的结果.

参考:<<算法笔记>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值