思路:
1,求出两个数中较大数的,小于其所有质数数列
2,分别求出两个数的质因数数列以及每个质因数被分解的次数
3,用另一个数列村两个数相同质因数,以及该质因数被分解两个数相比之下的最小次数
4,将上述数列的质因数分别做最小次数的幂并将结果相乘,就是最终的结果最大公约数
说得不够简洁,下面是举例:
n=12 ,m=24
小于m所有质数:2,3,5,7,11,13,17,19,23
n的质因数及次数:质因数 2 次数是 2
质因数 3 次数是 1
m的质因数及次数:质因数 2 次数是 3
质因数 3 次数是 1
得出两者结果:质因数 2 次数是 2
质因数 3 次数是 1
算出来公约数=2*2*3=12
#include<stdio.h>
#define MAX 1000
#define WHAT 1//只是随便取的名字,含义是whatever
int main(){
int a[MAX],b[MAX]={0},c[MAX]={0},d[MAX]={0},e[MAX]={0};
int i,j,k,n,m;
printf("请输入两个正整数\n");
scanf("%d%d",&n,&m);
for(i=0;i<MAX;i++)
a[i]=WHAT;//将数列全部置成非0
k=j=0;
if(n>=m){//找到n和m中稍大数的质数列
for(i=2;i<=n;i++){
if(a[i]!=0){
b[k]=i;
k++;
for(j=i+i;j<=n;j=j+i)
a[j]=0;
}
}
}
else{
for(i=2;i<=m;i++){
if(a[i]!=0){
b[k]=i;
k++;
for(j=i+i;j<=m;j=j+i)
a[j]=0;
}
}
}
printf("输出n和m中稍大数的质数列\n");
for(i=0;i<k;i++)
printf("%d ",b[i]);
//接下来是求n的质因数
int nn=n;
k=0;
while(nn!=1){
if(nn%b[k]==0){
nn=nn/b[k];
c[b[k]]++;
}
else{
k++;
}
}
printf("\n输出n的质因数\n");
for(i=0;i<MAX;i++)
if(c[i]!=0)
printf("%d %d\n",i,c[i]);//c[]数组的下标i是n的质因数,c[i]的值是n对于下标i分解的次数,例如12对于2的分解次数是2
//接下来是求m的质因数
int mm=m;
k=0;
while(mm!=1){
if(mm%b[k]==0){
mm=mm/b[k];
d[b[k]]++;
}
else{
k++;
}
}
printf("\n输出m的质因数\n");
for(i=0;i<MAX;i++)
if(d[i]!=0)
printf("%d %d\n",i,d[i]);
k=0;//找到n和m相同的质因数 以及 其最少的分解次数
for(i=0;i<MAX;i++){
if((c[i]!=0)&&(d[i]!=0)){
if(c[i]<=d[i]) e[i]=c[i];
else e[i]=d[i];
}
}
int end=1;//将相同的质因数也就是下标i取 最少次数e[i]的指数的所有结果相乘
for(i=0;i<MAX;i++){
if(e[i]!=0){
for(j=0;j<e[i];j++)
end=end*i;
}
}
printf("最大公约数为%d\n",end);
}
如果如图: