最大公约数

1.题目分析

①首先写出求最大公约数算法,用了四种方法,分别是,辗转相除法,穷举法,更相减损法,Stein算法,这四种方法通过不同的逻辑思维求出最大最大公约数,运行时间也各不相同。

②其次在进行编程时,要考虑到异常处理,求随机数的异常处理:超过数组范围,手动输入的异常处理:输入负数为不合法。

③还有就是用C语言中生产随机数及计算运行时间,并生成指定范围内指定个数的随机数。

④将获取的随机数运用在计算最大公约数的函数当中,最后用二维数组存放随机数,以把随机数以数组形式作为实参传入函数中。

 2.算法构造

  绘制出所有算法的流程图以及N-S盒图。

标题

 

3.算法实现

程序源代码(请写入必要的注释)。

#include"stdio.h"

#include<math.h>

#include<stdlib.h>

#include<time.h>

int divisor1(int a,int b);

int divisor2(int a,int b);

int gcd(int m,int n);

int Stein(unsigned int x,unsigned int y);

void main()

{

   clock_t start,finish;//开始结束两个时间  

   srand(10);

   double time;//定义运行时间

   int k,t1;

   int i,j,p;

    int min,max,n;

   int a[100][2];

   printf("你想随机产生多少组数:\n");

   scanf("%d",&n);

   if(n>100)

   {printf("超过数组范围,请重新输入:");

     scanf("%d",&n);

   }

   printf("请依次输入随机数取值的最小值,最大值(之后将在这个范围内产生随机数)\n");

   scanf("%d%d",&min,&max);

   

//      srand((unsigned)time(NULL));

   start=clock();//获取开始时间

    for(i=0;i<n;i++)//获取随机数并进行输出

   {

        for(j=0;j<2;j++)

        {

              a[i][j]=rand()%100;//将随机数赋给二维数组

            printf("%d ",a[i][j]);

        }

   }

   /*手动输入*/

   /*printf("输入两个数:");

   scanf("%d%d",&m,&n);

    for(;m<0||n<0;)

   {

        printf("输入数不合法,请重新输入:\n");

        scanf("%d%d",&m,&n1);

   }*/

   printf("\n方法1:辗转相除法;\n方法2:穷举法;\n方法3:更相减损法;\n方法4:Stein算法\n请选择:\n");

   scanf("%d",&k);//选择使用方法

   printf("最大公约数为:\n");

   for(p=0;p<n;p++)

   {

       

        switch(k)

        {

        case 1: {t1=divisor1(a[p][0],a[p][1]);//调用计算最大公约数的函数

              break;}

        case 2:{t1=divisor2(a[p][0],a[p][1]);

              break;}

        case 3:{t1=gcd(a[p][0],a[p][1]);

              break;}

        case 4:{t1=Stein(a[p][0],a[p][1]);

              break;}

        }

        printf("%d ",t1);

   }

   finish=clock();//获取结束时间

   printf("\n");

   time=(double)(finish-start)/CLOCKS_PER_SEC;

   printf("RunningTime:\n%f 毫秒\n",time);//显示运行时间

}

int divisor1(int a,int b)

{

   int temp;

   if(a<b)

   {

        temp=a;

        a=b;

        b=temp;

   }

   while(b!=0)//通过循环求两数的余数,直到余数为0

   {

        temp=a%b;

        a=b;

        b=temp;

   }

   return(a);

}

int divisor2(int a,int b)

{

   int temp;

   temp=(a>b)?b:a;//采用条件运算表达式求出两个数中的最小值

   while(temp>0)

   {

        if(a%temp==0&&b%temp==0)//只要找到一个数能同时被a,b所整除,则中止循环

              break;

        temp--;

   }

   return(temp);

}

int gcd(int m,int n)

{

   int i=0,temp,x;

   while(m%2==0 && n%2==0)  //判断m和n能被多少个2整除

   {

        m/=2;

        n/=2;

        i+=1;

   }

   if(m<n)     //m保存大的值

   {

        temp=m;

        m=n;

        n=temp;

   }

   while(x)

   {

        x=m-n;

        m=(n>x)?n:x;

        n=(n<x)?n:x;

        if(n==(m-n))

              break;

   }

   if(i==0)

        return n;

   else

        return (int )pow(2,i)*n;

}

 

int Stein(unsigned int x,unsigned int y)

{

   int factor=0;

   int temp;

   if(x<y)

   {

        temp=x;

        x=y;

        y=temp;

   }

   if(0==y)

   {

        return 0;

   }

   while(x!=y)

   {

        if(x&0x1)

        {

              if(y&0x1)

              {

                    y=(x-y)>>1;

                    x-=y;

              }

              else

              {

                    y>>=1;

              }

        }

        else

        {

              if(y&0x1)

              {

                    x>>=1;

                    if(x<y)

                    {

                          temp=x;

                          x=y;

                          y=temp;

                    }

              }

              else

              {

                    x>>=1;

                    y>>=1;

                    ++factor;

              }

        }

   }

   return (x<<factor);

}

 4.调试、测试及运行结果(至少比较4种GCD算法在给定不同规模测试数据的情况下的平均运行时间)

 

 

5、经验归纳

在本次上机中,我学到了输入两个数,求其最大公约数的算法,在其之上,做出改动,学习了如何在C语言中生产随机数及计算运行时间,并生成指定范围内指定个数的随机数,在time.h头文件下,先获取开始时间和结束时间start=clock(),finish=clock();最后计算运行时间time=(double)(finish-start)/CLOCKS_PER_SEC;

在比较4种不同算法在给定不同规模测试数据的情况下的平均运行时间后,得出辗转相除法所用时间最少,更相减损法用时最大;在编程中遇到的问题是,如何将获取的随机数运用在计算最大公约数的函数当中,最后我用了二维数组存放随机数,以把随机数以数组形式作为实参传入函数中。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值