给定某个正整数 N,求其素因子分解结果,即给出其因式分解表达式 N=p1k1⋅p2k2⋯pmkm。
答案:
#include <stdio.h>
#include <math.h>
int Isprime(int x) {
for (int i = 2; i <= sqrt(x); i++)
if (x % i == 0)
return 0;
return 1;
}
int arr[10000];
//桶的思想,arr每个元素都初始化为0,下标表示该数字,数组数值大于一的部分为对应下标数字取的次数
int main() {
long int n;
scanf("%ld", &n);
if (n == 0 || n == 1) //一定要对0与1特殊处理,我找了半天没想到是这里缺了
{
printf("%d=%d", n,n);
return 0; }
for (long int i = 2; i <= 10000; i++) {//建议i<=10000即可就够用了,不要写<=n,因为n太大数组会越界,发生段错误
if (Isprime(i))
arr[i]++;//将下标是素数的元素数值变为1
}
long int k = n;
//找质因子,详细分析见文章末
for (int i = 2; k != 1; i++)
if (arr[i]) { //i是素数
while (k % i == 0) {
k /= i;
arr[i]++;
}
}
int flag = 0;//是否为第一个数的标记,是为0不输出*,不是则输出*
printf("%ld=", n);
for (int i = 2; i <= 10000; i++) {
if (arr[i] > 1) {
if (flag)
printf("*");
else
flag = 1;
if (arr[i] > 2)
printf("%d^%d", i, arr[i] - 1);
else
printf("%d", i);//因为只有1次时输出中无^,所以分开写
}
}
return 0;
}
分析:
不妨举几个例子:
9 = 3^3
2 9%2!=0
3 9%3=0 (9/3)%3=0 9/3/3=0
9/3/3=1 -->end
12 = 2^2 * 3^1
2 12%2=0 (12/2)%2=0 (12/2/2)%2!=0
3 (12/2/2)%3=0
12/2/2/3=1 -->end
20 = 2^2 * 5^1
2 20%2=0 (20/2)%2=0 (20/2/2)%2!=0
3 (20/2/2)%3!=0
5 (20/2/2)%5=0
20/2/2/5=1 -->end
……
不难发现规律:
n从小的素数开始取余如果结果为0,这个素数次数+1,下次将n除以刚刚素数的结果赋值给n,再对n取余,如果取余结果不为0,则跳到下一个更大的素数取余,不断循环……
直到最后n变为1,结束循环即可。