算法学习|题目:求两个整数的最大公约数_欧几里得算法(基于Java)

求两个整数的最大公约数

知识补充:

例如:40与15的最大公约数为5
知识补充:
1)若数a能被数b整除(也称数b能整除数a),a就叫做b的倍数,b就叫做a的约数。
2)M与N的最大公约数:能够同时整除M、N的数中最大的一个数称为M与N的最大公约数。
3)整除的性质:若两个数都能被a整除,则它们的差(大数-小数)也能被a整除。
即:设数M、N(若M > N)能被a整除,则(M - N)也能被a整除
----证明:因为数M、N都能被a整除(M > N),所以可以设M = ai,N = aj(其中i、j为整数),则M - N = a*(i - j) --> (i - j)为整数,可得(M - N)也被a整除
4)性质推广:(M - kN)也被a整除(M > kN),其中k为整数
----证明:(M - kN) = ai - akj = a*(i - kj) --> (i - kj)为整数,可得(M - k*N)被a整除

5)结论:当M刚好大于kN时(即 kN < M < (k + 1)N ), (M - kN) == M % N,所以(M % N)被a整除
----证明:已知M = ai,N = aj
M - kN = a(i - kj) --> M = kN + a*(i - kj) --> M / N = k(商) ······ a(i - kj)(余数)
M % N = a
(i - kj) = (M - kN) 得证

分析:欧几里得算法(辗转相除法)+递归实现

欧几里德算法是用来求两个正整数最大公约数的算法。
假如需要求 1026 和 246 这两个正整数的最大公约数,用欧几里德算法,是这样进行的:
算法学习|题目:求两个整数的最大公约数_欧几里得算法(基于Java)_第1张图片
设函数 gcd(M,N) 实现求M、N的最大公约数,通过上述分析,利用欧几里得算法可以得:令M为被除数,N为除数进行除法运算,再将除数N作为被除数,得到的余数(M%N)作为除数继续运算。即 gcd(M,N) 转化为求 gcd(N,M%N)
利用递归实现
(递归不太熟悉的可以参考这篇文章:入门级递归算法题目)
1)找重复:①求最大公约数操作在重复
②递推公式:gcd(M,N) = gcd(N,M%N)
2)找变化量:gcd(M,N) - - - M变为N,N变为(M%N),求 gcd(M,N) 调用 gcd(N,M%N),求 gcd(N,M%N) 调用gcd( M%N,N%(M%N) ),如此往复
3)找出口:直到 gcd(M,N) 接受到的 N==0,即余数最终为0时,结束递归,返回当前算式中的除数M为最大公约数。

代码展示:

/*
	求M、N的最大公约数 --- 辗转相除法
		可以转换为求 N 与 (M % N)的最大公约数
		例:求40、15的最大公约数
		[M,N]
		[40,15] --> [15,(40 % 15)] = [15,10] -->
		[10,(15 % 10)] = [10,5] --> [5,(10 % 5)] --> [5,0] 
		--- 当最后余数N为0时结束运算,M==5即为最大公约数
 */

public class Test {
	public static void main(String[] args) {
		int M = 1026;
		int N = 246;
		//测试输出结果
		System.out.println(M+","+N+"的最大公约数为:"+gcd(M,N));
	}
	//gcd()函数用于求最大公约数
	static int gcd(int M,int N) {
		//设置出口
		if(N == 0) {
			return M;
		}
		//调用自身
		return gcd(N,M % N);
	}
}

骚话时刻:
恭喜你,到这一刻你已经膜拜完我们的欧几里得大神
有一种很好的学习方法想要跟大家分享一下
俗话说读万卷书不如行万里路
如若 文不如字,字不如表,表不如图








算法学习|题目:求两个整数的最大公约数_欧几里得算法(基于Java)_第2张图片
没错,这就是欧几里得
至此,大家已经非常生动形象地学习完了欧几里得算法
算法学习|题目:求两个整数的最大公约数_欧几里得算法(基于Java)_第3张图片

你可能感兴趣的:(算法,Java,算法题目,递归,欧几里得)