王道机试练习——分解素因数

王道机试练习——分解素因数

题目描述

求正整数 N(N>1)的质因数的个数。 相同的质因数需要重复计算。如 120=22235 ,共有 5 个质因数。 输入: 可能有多组测试数据,每组测试数据的输入是一个正整数 N,(1<N<10^9)。
输出: 对于每组数据,输出 N 的质因数的个数。
样例输入:
120
样例输出:
5

步骤以及原理

该代码按照如下步骤对输入的整数分解素因数:
1.利用素数筛法筛得 0 到 100000 区间内所有素数。
2.输入 n。
3.依次测试步骤 1 中得到的素数能否整除 n,若能则表明该素数为它的一个
素因数。
4.不断将 n 除以该素数,直到不能再被整除为止,同时统计其幂指数。
5.若在完成某个素数的幂指数统计后, n 变为 1,则表明 n 的所有素因数全 部被分解出来,这样就不用再去遍历后续的素数,分解活动提前终止。
6.若遍历、测试、分解完所有预处理出来的素数, n 仍旧没被除成 1,则表 明 n 存在一个大于 100000 的因子,且该因子必为其素因子,且其幂指数必然为 1。
我们首先说明为什么素数筛法只需筛到 100000 即可,而不是与输入数据同 规模的 1000000000。这样处理的理论依据是: n 至多只存在一个大于 sqrt(n) 的素因数(否则两个大于 sqrt(n)的数相乘即大于 n)。这样,我们只需将 n 所 有小于 sqrt(n)的素数从 n 中除去,剩余的部分必为该大素因数。正是由于这 样的原因,我们不必依次测试 sqrt(n)到 n 的素数,而是在处理完小于 sqrt(n) 的素因数时,就能确定是否存在该大素因数,若存在其幂指数也必为 1。 在完成查找素因数的工作以后,我们只需简单的把所有素因数对应的幂指数 相加,即可得到该整数素因数的个数。顺便一提的是,当我们完成素因数分解后 我们同样可以确定被分解整数因数的个数为 (e1 1) * (e2 1) ( en 1)(由所 有的素因数不同组合数得出)。

代码

#include<iostream>
using namespace std;
bool mark[100001];
int prime[100001];
int primeSize;
void init() {
	primeSize = 0;
	for (int i = 2; i < 100000; i++) {
		if (mark[i] == true)continue;
		prime[primeSize++] = i;
		if (i >= 1000)continue;
		for (int j = i * i; j <= 100000; j += i) {
			mark[j] = true;
		}
	}
}
int main() {
	init();
	int n;
	while (cin >> n) {
		int ansPrime[30];//按顺序保存分解出的素因数
		int ansSize = 0;//分解出素因数的个数
		int ansNum[30];//保存分解出的素因数对应的幂指数
		for (int i = 0; i < primeSize; i++) {//依次测试每一个素数
			if (n % prime[i] == 0) {//若该素数能整除被分解数
				ansPrime[ansSize] = prime[i];//则该素数为其素数
				ansNum[ansSize] = 0;//初始化幂指数为0
				while (n % prime[i] == 0) {//从被测试数中将该素数分解出来,并统计其幂指数
					ansNum[ansSize]++;
					n /= prime[i];
				}
				ansSize++;//素因数个数增加
				if (n == 1)break;//若已经被分解为1,则分解提前终止

			}
		}
		if (n != 1) {//若测试完2到100000内所有的素数,n仍未被分解至1,则剩余的因数一定是
			//一个大于100000的素因数
			ansPrime[ansSize] = n;//记录该大素因数
			ansNum[ansSize++] = 1;//其幂指数只能为1
		}
		int ans = 0;
		for (int i = 0; i < ansSize; i++) {
			ans += ansNum[i];//统计各个素因数的幂指数
		}
		cout << ans;//输出
	}
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值