四种方法求最大公约数

一、题目分析
实验题目:运行最大公约数的常用算法,并进行程序的调式与测试,要求程序设计风格良好,并添加异常处理模块(如输入非法等)。
分析:运用四种算法分别计算最大公约数,并选择手动输入数据验证算法正确和产生20组数据比较算法优劣
二、算法构造
1,辗转相除法
在这里插入图片描述
2,穷举法

在这里插入图片描述
3,更相减损法
在这里插入图片描述
4,Stein算法
在这里插入图片描述

三,算法实现

#include<iostream>

#include<stdio.h>

#include<time.h>

#include<math.h>

#include<stdlib.h>
using namespace std;
class Number
{
private:
    int num1;
    int num2;
public:
    void set();
    bool judge();
    void zhanzhuan();//辗转相除法
    void Qiongqu();//穷举法
    void Genxiang();//更相减损法
    void Stein();
    int  Stein(int a,int b);//Stein法
};
void Number::set()//输入函数

{
    cin>>num1>>num2;
}

bool Number::judge()//判断输入的值是否正确
{
    bool flag;
    if(num1>0&&num2>0)
        flag=false;
    else
        flag=true;
    if(flag)
    {
        cout<<"数据输入错误,请重新输入:"<<endl;
        cin>>num1>>num2;
    }
    return flag;
}


void Number::zhanzhuan()
{
    int a=num1;
    int b=num2;
    int t1,temp;        
    if(a<b)              //求出最大值和最小值
    {
        temp=a;
        a=b;
        b=temp;
    }

    do                    //通过循环求两束的余数,直到余数为0
    {
        t1=a%b;
        a=b;              //变量数值交换
        b=t1;
    }while(t1!=0);
       cout<<"这两个数的最大公约数为:"<<a<<endl;

}



void Number::Qiongqu()

{
    int a=num1;
    int b=num2;
    int temp,t1;
    temp=(a>b)?b:a;          //求出最小值
    while(temp>0)
    {
        if(a%temp==0&&b%temp==0)  break;//只要找到一个数能同时被a,b整除,则停止循环
        temp--;
    }
    t1=temp;
    cout<<"这两个数的最大公约数为:"<<t1<<endl;
}


void Number::Genxiang()
{
    int a=num1;
    int b=num2;
    int i=0,temp,x;
    while(a%2==0&&b%2==0)      //判断a,b能被多少个2整除
    {
        a=a/2;
        b=b/2;
        i=i+1;
    }
    if(a<b)            //a保存最大值
    {
        temp=a;
        a=b;
        b=temp;
    }
    while(x)
    {
        x=a-b;         //较大的值减去较小的值,接着吧所得的差与较小的数比较,并以大数减小数。
        a=(b>x)?b:x;
        b=(b<x)?b:x;
        if(b==a) //值到所得的减数和差相等
            break;
    }
    if(i==0)
    cout<<"这两个数的最大公约数为:"<<b<<endl;    
    else
    cout<<"这两个数的最大公约数为:"<<pow(2,i)*b<<endl;

 
}


int Number::Stein(int a,int b)

{
    if (a < b)//将a,b中将的数给a,小的给b
    {
        int temp=0;
        temp=a;
        a=b;
        b=temp;
                }

    if (b == 0) return a;
    if((a&0x1)==0&&(b&0x1)==0) return 2*Stein(a>>1,b>>1);  //两数都是偶数
    if((a&0x1)==0&&(b&0x1)!=0) return Stein(a>>1,b); //一偶一奇
    if((a&0x1)!=0&&(b&0x1)==0) return Stein(a,b>>1);  //一奇一偶
    if((a&0x1)!=0&&(b&0x1)!=0) return Stein((a-b)>>1,b);//两数都是奇数
}

    
void Number::Stein()

{
    int x,y,z;
    x=num1;
    y=num2;
    z=Stein(x,y);
    cout<<z<<endl;

}

    int main()
    {
        clock_t start, finish;    //时间函数
        int x,y;
        bool isFalse=true;
        Number n;
        {
            cout<<"请输入两个整数"<<endl;
            n.set();
            while(isFalse)
            {
                isFalse=n.judge ();
            }
                    cout<<"辗转相除法:"<<endl;
                start=clock();n.zhanzhuan();finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
                    cout<<"穷举法:"<<endl;
                start=clock();n.Qiongqu(); finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
                    cout<<"更相减损法:"<<endl;
                start=clock();n.Genxiang();finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
                    cout<<"Stein法:"<<endl;
                start=clock();n.Stein();finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
    
        return 0;

    }

    }

四,调试,测试及运行结果
a.测试调试
20组数据:在这里插入图片描述
以上方法依次测试数据
1.在这里插入图片描述
2,在这里插入图片描述
3, 在这里插入图片描述
4,在这里插入图片描述
b。运行结果

在这里插入图片描述五、总结
1,学习到了计算最大公约数的四种方法,辗转相除法容易理解但运算繁杂,易错,该算法运算时间长等不足,更相减损法和辗转相除法相比算法更精炼,更相减损法避免了求余运算,但两数相差过大时,递归次数会非常多,影响算法性能
2.通过对异常的处理,学习到自己没掌握的知识。
3,Stein算法只有整数的移位和加减法。
4,学会了对时间函数的应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值