求最大公约数的两种解法(欧几里得算法和素数分解)

最大公约数的两种解法(欧几里得算法和素数分解)

方法一: 欧几里得算法,又称辗转相除法

定理(欧几里得算法):设a和b是正整数,则存在最大求最大公因子d=(a,b)的一种算法,且存在求一组整数s,t使得d = sa+tb

举个例子:求168和60的最大公约数?

168 = 2 * 60 + 48

60  = 1 * 48 +12

48  = 4 * 12

由此得最大公约数为12

关于最大公倍数

C语言程序代码:很简单就不加注释了

#include<stdio.h>
#define SWAP(a,b) {a=a+b; b=a-b; a=a-b; }
int gcd(int a,int b)
{
	if(a==b)
		return a;
	if(a<b)
		SWAP(a,b);
	int temp = 0;
	while(a%b)
	{
		temp = b;
		b = a % b;
		a = temp;
	}
	return b;
}
int main()
{
	int a = 168;
	int b = 60;
	printf("最大公约数是: %d\n",gcd(a,b));
	return 0;
}

方法二:素数分解

我们知道每一个大于等于2的整数都可以表示为几个素数相乘的形式(算术基本定理)而且有其对应的唯一的分解式,利用这点我们也可以用来求解最大公因子(最大公约数)

例如:在上题中168 可以表示为pow(2,3)*pow(3,1)*pow(5,0)*pow(7,1)

60可以表示为pow(2,2)*pow(3,1)*pow(5,1)*pow(7,0)

所以(168,60) = pow*(2,2)*pow(3,1)*pow(5,0)*pow(7,0) = 12

#include<stdio.h>
#include<math.h>
#define COUNT_PRIME 10
void Divisor(int num,int prime[],int index,int& loop)//求分解的因子的个数
{
	if(num==1)
		return;
	int count = 0;
	while(num%index==0)
	{
		num /= index;
		count++;
	}
	if(index==2)
	{
		prime[index-2] = count;
		index += 1;
	}
	else
	{
		prime[index/2] = count;
		index += 2;
	}
	Divisor(num,prime,index,loop);
	loop += 1;
}
int Gcd(int a[],int b[],int loop_a,int loop_b)//求解最大公因子
{
	int gcd = a[0]<b[0]?pow(2,a[0]):pow(2,b[0]);
	for(int i=1,j=3;i<loop_a||i<loop_b;i++,j+=2)
	{
		int num = a[i]<b[i]?pow(j,a[i]):pow(j,b[i]);
		gcd *= num;
	}
	return gcd;
}
int main()
{
	int a = 60,b = 168;
	int prime_a[COUNT_PRIME] = {0};
	int prime_b[COUNT_PRIME] = {0};
	int loop_a = 0,loop_b = 0;
	Divisor(a,prime_a,2,loop_a);
	Divisor(b,prime_b,2,loop_b);
	int gcd = Gcd(prime_a,prime_b,loop_a,loop_b);
	printf("最大公约数是: %d\n",gcd);
	printf("最大公倍数是: %d\n",a*b/gcd);
	return 0;
}

这里主要的函数在于求各个因子的个数,我使用了递归来解决这个问题

时间: 2025-01-02 04:57:30

求最大公约数的两种解法(欧几里得算法和素数分解)的相关文章

js求最大公约数的两种方法

1.辗转相除法 function commonDivisor1(num1,num2) { if ((num1-num2) < 0) { var k = num1; num1 = num2; num2 = k; } while (num2 !=0) { var remainder = num1%num2; num1 = num2; num2 = remainder; } return num1; } 2.更相减损法 function commonDivisor2(num1,num2) { var

2.7 编程之美--最大公约数的3种解法[efficient method to solve gcd problem]

[本文链接] http://www.cnblogs.com/hellogiser/p/efficient-method-to-solve-gcd-problem.html [题目] 求两个正整数的最大公约数Greatest Common Divisor (GCD).如果两个正整数都很大,有什么简单的算法吗?例如,给定两个数1 100 100 210 001, 120 200 021,求出其最大公约数. [解法] [1. 辗转相除法] 辗转相除法:f(x,y) = f(y , x % y)(x>y

求最大公约数的几种算法分析

题目--求两个整数的最大公约数 思路1.穷举算法 public static voidmain(String[] args) throws IOException { Scannerscanner = new Scanner(System.in); inta = scanner.nextInt(); intb = scanner.nextInt(); System.out.println("开始时间是"+System.currentTimeMillis()); System.out.p

统计逆序对的两种解法

统计逆序对的两种解法 归并排序(mergeSort) 逆序对定义 \(i<j\) 但\(a[i]>a[j]\),假设我们分别使得通过mergeSort使得左右半边有序 即\(a[1]...a[mid]\) 递增, \(a[mid+1]....a[n]\)递增,我们需要通过merge操作,完成整个的排序和新增逆序对的计数,较小值出现在左半边记为 a[i],出现在右半边即为 a[j],那么每次出现在右半边,意味左半边比a[i]大的数都比a[j]大,由此可以统计逆序对 HDU1394 代码实现 #i

hdu 4521 小明系列问题——小明序列 (间隔至少为d的LIS 两种解法)

先附上资源地址:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html 进程(process)和线程(thread)是操作系统的基本概念,但是它们比较抽象,不容易掌握. 最近,我读到一篇材料,发现有一个很好的类比,可以把它们解释地清晰易懂. 1. 计算机的核心是CPU,它承担了所有的计算任务.它就像一座工厂,时刻在运行. 2. 假定工厂的电力有限,一次只能供给一个车间使用.也就是说,一个车间开工的时候,其他车间都必须停工

POJ 1515 Street Directions --一道连通题的双连通和强连通两种解法

题意:将一个无向图中的双向边改成单向边使图强连通,问最多能改多少条边,输出改造后的图. 分析: 1.双连通做法: 双连通图转强连通图的算法:对双连通图进行dfs,在搜索的过程中就能按照搜索的方向给所有边定向,其中桥不能改造,只能保留双向边. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #includ

C语言--求字符串长度的三种解法

问题: 求一个字符串的三种解法 一.计数的方法 #include<stdio.h> #include<assert.h> int my_strlen( char* str) { int count=0; while (*str) { count++; str++; } return count; } int main(void) { char *arr = "abcef"; int ret = my_strlen(arr); printf("%d\n&

POJ 3628 Bookshelf 2 0/1背包和DFS两种解法

题目链接:POJ 3628 Bookshelf 2 Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7462   Accepted: 3436 Description Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled up quite quickly,

VB求最大公约数的两个例子

VB求最大公约数的两个算法 Private Sub Command1_Click() Dim a As Long, b As Long a = InputBox("请输入要求最大公约数的整数", " 求两数的最大公约数:step1", 0) b = InputBox("请输入要求最大公约数的整数", " 求两数的最大公约数:step2", 0) Print "step1>>>整数1 : "