求最大公约数

题目:求解最大公约数
算法实现:
(1)辗转相除法:
步骤一:若a%b为0,则b就是a,b的最大公约数;
步骤一:a%b不为0,将b赋值给a,a%b赋值g给b,重复步骤一
(2)穷举法:
求出a,b中较小的值min,让min值逐渐减小到一,过程中如果a,b%min都为0,则此时的min就是最大公约数
(3)更相减损法:
第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数
(4)stein法:
对两个正整数 x>y :
1.均为偶数 gcd( x,y ) =2gcd( x/2,y/2 );
2.均为奇数 gcd( x,y ) = gcd( (x+y)/2,(x-y)/2 );
2.x奇y偶 gcd( x,y ) = gcd( x,y/2 );
3.x偶y奇 gcd( x,y ) = gcd( x/2,y ) 或 gcd( x,y )=gcd( y,x/2 );
当x==y时,递归结束。
C语言实现

#include<stdio.h>
#include<time.h>
#include<math.h>


//	辗转相除法求最大公约数——循环实现
int divsion1(int a, int b){
	//	检查数据输入合法性
	if (a < 1 || b < 1){
		return -1;
	}

	int c;
	while (c = a % b){
		a = b;
		b = c;
	}

	return b;
}

//	辗转相除法求最大公约数——递归实现
int divsion2(int a, int b){
	//	检查数据输入合法性
	if (a < 1 || b < 1){
		return -1;
	}

	if (a % b){
		return divsion2(b, a%b);
	}

	return b;
}


//	枚举法求最大公约数
int enumComputing(int a, int b){
	int min = a < b ? a : b;

	for (; min > 1 && (a % min || b % min); min--);

	return min;
}
//	枚举法求最大公约数
int enumMinMultiple(int a, int b){
	int max = a > b ? a : b;
	int min = a < b ? a : b;
	int t = max;

	while (max % min){
		max += t;
	}

	return max;
}


//	更像减损法求最大公约数
int getMinMultiple(int a, int b){
	int n = 0;

	while (a % 2 == 0 && b % 2 == 0){
		a /= 2;
		b /= 2;
		n++;
	}

	if (a < b){
		int t = a;
		a = b;
		b = t;
	}

	int x = a - b;
	while (x){
		a = b > x ? b : x;
		b = b < x ? b : x;
		if (a - b == b){
			break;
		}
		x = a - b;
	}

	if (! n){
		return b;
	}
	return pow (2, n) * b; 
}

//	stein算法
int stein (int a, int b){
	if (a == b){
		return a;
	}
	
	if(a % 2 == 0){
		if (b % 2 == 0){
			return 2 * stein(a/2, b/2);
		}else{
			return stein(a/2, b);
		}
	}else{
		if (b % 2 == 0){
			return stein(a, b/2);
		}else{
			return stein((int)fabs(a - b) / 2, (a + b) / 2);
		}
	}
} 

//	测试模块:通过传入函数的编号,测试对应函数模块并返回运行时间 
double test(int n){
	int i;
	clock_t start,end;
	int a[10][2]={{2,4},{24,36},{45,12332},{456,235464},{5534555,545},{676,68},{12,124464640},{10046500,50},{45645,4234},{234,8}};

	start = clock();

	switch(n){
	case 1 :
		for(i = 0; i < 10; i++){
			int t = divsion1(a[i][0], a[i][1]);
			printf("%d,%d的最大公约数为:%d,最小公倍数为:%d\n",a[i][0], a[i][1], t, a[i][0]*a[i][1] / t);
		}
		end = clock();
		break;
	case 2:
		for(i = 0; i < 10; i++){
			int t = divsion2(a[i][0], a[i][1]);
			printf("%d,%d的最大公约数为:%d,最小公倍数为:%d\n",a[i][0], a[i][1], t, a[i][0] *a [i][1] / t);
		}
		end = clock();
		break;
	case 3:
		for(i = 0; i < 10; i++){
			int t = enumComputing(a[i][0], a[i][1]);
			printf("%d,%d的最大公约数为:%d,最小公倍数为:%d\n",a[i][0], a[i][1], t, enumMinMultiple(a[i][0], a[i][1]));
		}
		end = clock();
		break;
	case 4:
		for(i = 0; i < 10; i++){
			int t = getMinMultiple(a[i][0], a[i][1]);
			printf("%d,%d的最大公约数为:%d,最小公倍数为:%d\n",a[i][0], a[i][1], t, a[i][0] * a[i][1] / t);
		}
		end = clock();
		break;
	case 5:
		for(i = 0; i < 10; i++){
			int t = stein(a[i][0], a[i][1]);
			printf("%d,%d的最大公约数为:%d,最小公倍数为:%d\n",a[i][0], a[i][1], t, a[i][0] * a[i][1] / t);
		}
		end = clock();
		break;
	}

	return (double) (end-start)/CLOCKS_PER_SEC;
}



int main(void){
	int n;

	while(1){
		printf("输入调用哪种求解最大公约数的函数函数编号:");
		scanf("%d",&n);
		printf("\n运行时间为:%lfseconds\n\n",test(n));
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值