问题及代码:
1、连续整数检测法。
2、欧几里得算法
3、分解质因数算法
根据实现提示写代码并分析代码的时间复杂度:
方法一:
int f1(int m,intn)
{
int t;
if(m>n)t=n;
else t=m;
while(t)
{
if(m%t==0&&n%t==0)break;
else t=t-1;
}
return t;
}
根据代码考虑最坏情况他们的最大公约数是1,循环做了t-1次,最好情况是只做了1次,可以得出O(n)=n/2;
方法二:
int f2(int m,int n)
{
int r;
r=m%n;
while(r!=0)
{
m=n;
n=r;
r=m%n;
}
return n;
}
根据代码辗转相除得到欧几里得的O(n)= log n
方法三:
int f3(int m,intn)
{
int i=2,j=0,h=0;
int a[N],b[N],c[N];
while(i<n)
{
if(n%i==0)
{
j++;
a[j]=i;
n=n/i;
}
else i++;
}
j++;
a[j]=n;
i=1;
int u;
u=j;
while(i<=j)
{
//printf("%d ",a[i]);
i++;
}
i=2;
j=0;
while(i<m)
{
if(m%i==0)
{
j++;
b[j]=i;
m=m/i;
}
else i++;
}
j++;
b[j]=m;
i=1;
while(i<=j)
{
//printf("%d ",b[i]);
i++;
}
int k=1;
for(i=1; i<=j; i++)
{
for(k=1; k<=u; k++)
{
if(b[i]==a[k])
{
h++;
c[h]=a[k];//printf("%d ",c[h]);
a[k]=a[k+1];
break;
}
}
}
k=1;
while(h>1)
{
k=k*c[h]*c[h-1];
h=h-2;
}
if(h==1)
{
k=k*c[1];
return k;
}
else return k;
}
根据代码分解质因子算法O(n)=n2+n/2
/*
*Copyright (c)2015,烟台大学计算机与控制工程学院
*All rights reserved.
*文件名称:gcd.cpp
*作 者:单昕昕
*完成日期:2015年2月13日
*版 本 号:v1.0
*
*问题描述:
1、连续整数检测法。
2、欧几里得算法
3、分解质因数算法
根据实现提示写代码并分析代码的时间复杂度
*程序输入:两个整数。
*程序输出:两个整数的最大公约数,计算每种算法运行的次数所用的时间。
*/
#include"stdio.h"
#include"stdlib.h"
#include"time.h"
#define N 100
int w,w2,w3;//用于计数
int f1(int m,int n)
{
int t;
if(m>n)t=n;
else t=m;
while(t)
{
if(m%t==0&&n%t==0)break;
else t=t-1;
w++;
}
return t;
}
int f2(int m,int n)
{
int r;
r=m%n;
w2=1;
while(r!=0)
{
m=n;
n=r;
r=m%n;
w2++;
}
return n;
}
int f3(int m,int n)
{
int i=2,j=0,h=0;
int a[N],b[N],c[N];
while(i<n)
{
if(n%i==0)
{
j++;
a[j]=i;
n=n/i;
w3++;
}
else
{
i++;
w3++;
}
}
j++;
a[j]=n;
i=1;
int u;
u=j;
while(i<=j)
{
//printf("%d ",a[i]);
i++;
w3++;
}
//printf("\n");
i=2;
j=0;
while(i<m)
{
if(m%i==0)
{
j++;
b[j]=i;
m=m/i;
w3++;
}
else
{
i++;
w3++;
}
}
j++;
b[j]=m;
i=1;
while(i<=j)
{
//printf("%d ",b[i]);
i++;
w3++;
}
int k=1;
for(i=1; i<=j; i++)
{
for(k=1; k<=u; k++)
{
if(b[i]==a[k])
{
w3++;
h++;
c[h]=a[k];//printf("\n%d ",c[h]);
a[k]=a[k+1];
break;
}
}
}
k=1;
while(h>1)
{
k=k*c[h]*c[h-1];
h=h-2;
w3++;
}
if(h==1)
{
k=k*c[1];
return k;
}
else return k;
}
int main(void)
{
int m,n;
printf(" 请输入m、n :\n");
scanf("%d%d",&m,&n);
int k;
k=f1(m,n);
printf(" 方法一最大公约数为: %d\n",k);
k=f2(m,n);
printf(" 方法二最大公约数为: %d\n",k);
k=f3(m,n);
printf(" 方法三最大公约数为: %d\n",k);
printf("\n--------------------\n");
printf("\n计数器显示结果:\n\n\n");
printf("方法一: %d \n",w2);
printf("方法二: %d \n",w);
printf("方法三: %d \n",w3);
printf("\n--------------------\n");
float i;
clock_t start,finish;
double usetime;
i=0;
start= clock();
while (i<1000000)
{
f1(m,n);
i++;
}
finish=clock();
usetime= finish-start;
printf(" 方法一用时%.f*10^(-6) 毫秒\n", usetime);
i=0;
start= clock();
while (i<1000000)
{
f2(m,n);
i++;
}
finish=clock();
usetime= finish-start;
printf(" 方法二用时%.f*10^(-6) 毫秒\n", usetime);
i=0;
start= clock();
while (i<1000000)
{
f3(m,n);
i++;
}
finish=clock();
usetime= finish-start;
printf(" 方法三用时%.f*10^(-6) 毫秒\n", usetime);
}
运行结果:
计数器采用的是没做一次循环就加1;
计时器是记住开始时间和结束时间,用结束时间减开始时间。
学习心得:
很明显,欧几里得算法也就是我们常用的辗转相除法比较省时。