描述
题目描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
数据范围:
1
⩽
n
⩽
2
×
1
0
9
+
14
1\leqslant n\leqslant 2×10^{9}+14
1⩽n⩽2×109+14
输入描述
输入一个整数。
输出描述
按照从小到大的顺序输出它的所有质数的因子,以空格隔开。
示例
输入:
180
输出:
2 2 3 3 5
代码
本代码采用试除法。
#include<stdio.h>
#include<math.h>
int isprime(int n) {
int flag = 1;
int i = 0;
for (i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
flag = 0;
break;
}
}
return flag;
}
int main() {
//1、用min和max变量确定你要求质因数的数的范围
int min = 1;
int max = 2 * pow(10, 9) + 14;
int i = 0;
int j = 0;
if(scanf("%d", &i) >= min && scanf("%d", &i) <= max) {
//2、写一个判断是否为素数的函数isprime()
//如果是素数直接写出该素数=该素数
//如果判断为合数,就要用合数分解质因数的方法。
if (isprime(i)) {
//为真则为质数,直接输出
printf("%d\n", i);
} else {
//既然进了else就说明是合数了
int tmp = i;//tmp为临时保存i的值,防止i在后面的操作中被改变
for (j = 2; j < tmp; j++) {
//这里j从二开始,因为我此时分解合数,最小的质数是2,所以从2开始
//还应注意的是必须是j<tmp,如果多一个=,那还分解什么合数,直接等于本身*1了
if (isprime(j)) {
//判断是否为质数,因为分解质因数的前提是因子必须为质数的前提下
while (tmp % j == 0) {
printf("%d ", j);
tmp /= j;//tmp /= j就是tmp = tmp/j
if (isprime(tmp)) {
//一直除以质因子,直到有一次除出来结果是质数,说明分解质因数完毕
printf("%d ", tmp);
break;
}
}
}
}
}
}
return 0;
}
质数因子相关知识
质数
质数,又称素数,若一个正整数无法被除了1和它自身以外的其它数整除,则称其为质数,否则为合数。特殊地,1既不是合数也不是质数。
质数因子
如果一个数的因数是质数,那么这个因数就是他的质数因子。
质因数分解
试除法(基本方法)
从最小的质数开始,逐步尝试是否能整除给定的数。如果能够整除,则将该数作为质因子,并继续对商进行相同的操作,直到商为1为止。具体步骤如下:
1、对于一个待分解的数n(n>2),从2开始依次尝试将其除尽。
2、如果能够整除,则将该数作为n的一个质因子,然后继续对商进行相同的操作。
3、直到商为1为止。
高级方法
对于较大的数,试除法效率较低。因此,出现了多种高效的算法:
1、Pollard Rho算法:通过随机选择一个函数并使用迭代过程找到非平凡因子。
2、Shor算法:利用量子计算实现指数加速,可以在多项式时间内解决大数分解问题。
3、线性筛:预处理出一个数组记录每个数的最小质因子,在分解时可以快速找到质因子。