求最大公约数的4种算法

一、题目分析

欲运行四种求最大公约数的算法,并比较在不同测试数据规模下四种算法的平均运行时间
用文字描述步骤

  • 输入测试数据的规模(数组大小);
  • 调用random()函数,创建数组;
  • 定义clock_t变量start,记录开始时刻;
  • 调用求公约数函数,求出最大公约数;
  • 定义clock_t变量stop,记录结束时刻;
  • 输出运行时间;

二、算法流程图

辗转相除法穷举法更相减损法Stein算法

三、源代码

/**
*  文件名:main.cpp
*  描述:完成求两个数的最大公约数问题,并输出“求公约数”的操作的运行时间
**/
#include"iostream"
#include<cstdlib>
#include<time.h>
#include"algorithm.h"

/*randomInt(a,b)规定生成的随机数在[a,b]范围内*/
#define randomInt(a,b) (rand()%(b-a+1)+a)
using namespace std;

int main()
{
	char ch;
	int n;
	cout << "需要求多少组数据的最大公约数:";
	cin >> n;

	/*使用new动态分配存储空间,建立动态数组*/
	int(*p)[2] = new int[n][2];

	//生成随机数
	srand((unsigned)time(NULL));
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < 2; j++)
		{
            //生成一个[1,1000]之间的随机数
			p[i][j]=randomInt(1,1000);
		}
	}
	cout << "可选择的求最大公约数的方法:" << endl;
	cout << "1. 辗转相除法" << endl;
	cout << "2. 穷举法" << endl;
	cout << "3. 更相减损法" << endl;
	cout << "4. Stein算法" << endl;
	/*可重复选择*/
	do{
		cout << "输入序号,选择计算的方法:";
		int k;
		cin >> k;
		//得出算法运行时间
		double ret;
		clock_t start = clock();//调取开始操作时系统时间
		switch (k)
		{
		case 1:
			for (int i = 0; i < n; i++)
			{
				int a = Zhan_Zhuan(p[i][0], p[i][1]);
			}
			break;
		case 2:
			for (int i = 0; i < n; i++)
			{
				int a = Qiong_Ju(p[i][0], p[i][1]);
			}
			break;
		case 3:
			for (int i = 0; i < n; i++)
			{
				int a = Geng_Xiang(p[i][0], p[i][1]);
			}
			break;
		case 4:
			for (int i = 0; i < n; i++)
			{
				int a = Stein(p[i][0], p[i][1]);
			}
			break;
		default:
			cout << "序号错误!" << endl;
			break;
		}
		if(k<=4&&k>=1)
		{
		clock_t stop = clock();//调取结束操作时系统时间
		ret = (double)(stop - start);
		cout << "算法运行时间:" << ret << "ms";
		}
		cout << endl;
		cout << "继续吗,(y/n):"<<endl;
		ch = getchar();
		ch = getchar();
	} while (ch == 'y'||ch=='Y');
	/*释放动态存储空间*/
	delete[]p;
	system("pause");
}
/**
*  文件名:algorithm.h
*  描述:包含求最大公约数的四种算法的函数声明
*  函数列表:
   1.Zhan_Zhuan();//辗转相除法
   2.Qiong_Ju();  //穷举法
   3.Geng_Xiang();//更相减损法
   4.Stein();    //Stein算法
**/

#pragma once
#ifndef ALGORITHM_H
#define ALGORITHM_H

int Zhan_Zhuan(int, int);
int Qiong_Ju(int, int);
int Geng_Xiang(int, int);
int Stein(int, int);
#endif
/**
*  文件名:algorithm.cpp
*  描述:包含对应函数定义
*  函数列表:
   1.Zhan_Zhuan();//辗转相除法
   2.Qiong_Ju();  //穷举法
   3.Geng_Xiang();//更相减损法
   4.Stein();    //Stein算法
**/

#include "algorithm.h"

/**
*  描述:辗转相除法
   传值给a, b开始求两个数的最大公约数,结果作为函数返回值输出
**/
int Zhan_Zhuan(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);            /*返回最大公约数到调用函数处*/
	}
}

/**
*  描述:穷举法
   传值给a, b开始求两个数的最大公约数,结果作为函数返回值输出
**/
int Qiong_Ju(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--;      /*如不满足if条件则变量自减,直到能被a,b所整除*/
	}
	return (temp); /*返回满足条件的数到主调函数处*/
}

/**
*  描述:更相减损法
   传值给a, b开始求两个数的最大公约数,结果作为函数返回值输出
**/
int Geng_Xiang(int a, int b)
{
	int ans = 1;//储存第一步中约掉的若干个2
	int gcd;//储存最终返回的结果 
	while (a % 2 == 0 && b % 2 == 0)//如果a,b均为偶数则用2约简 
	{
		a /= 2;
		b /= 2;
		ans *= 2;
	}
	while (a != b)//判断两数是否相等,相等则得出最大约数
	{
		if (a > b)
			a -= b;//以较大的数减较小的数
		else
			b -= a;//以较大的数减较小的数
	}
	gcd = a * ans; //求第一步中约掉的若干个2与第二步中等数的乘积 
	return gcd;
}

/**
*  描述:Stein算法
   传值给a, b开始求两个数的最大公约数,结果作为函数返回值输出
**/
int Stein(int x, 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)
		{/* when x is odd */
			if (y & 0x1)
			{/* when x and y are both odd */
				y = (x - y) >> 1;
				x -= y;
			}
			else
			{/* when x is odd and y is even */
				y >>= 1;
			}
		}
		else
		{/* when x is even */
			if (y & 0x1)
			{/* when x is even and y is odd */
				x >>= 1;
				if (x < y)
				{
					temp = x;
					x = y;
					y = temp;
				}
			}
			else
			{/* when x and y are both even */
				x >>= 1;
				y >>= 1;
				++factor;
			}
		}
	}
	return (x << factor);
}

四、运行结果

结果

五、总结

一个完整的程序设计环节是环环相扣的,问题分析,用文字将步骤完整的描述出来,对我个人而言,这步工作能够保证整个编程过程清晰明确,接着测试,调试,步步相辅,最终得到结果。
过程中,了解到灵活使用位运算符有时候会带来很好的效果,利用new动态分配存储空间达到创建动态数组的目的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值