我知道扩展的欧几里得算法是什么以及它在编程中使用的原因。这是一种非常有用的算法,用于查找数的逆模。我知道如何用c ++实现它,这就是我在c ++中实现它的方法。
typedef pair<int, int> pii;
#define x first
#define y second
pii extendedEuclidean(int a, int b)
{
if(b==0)
return {a,0};
else {
pii d = extendedEuclidean(b, a%b);
return {d.y, d.x - (d.y*(a/b))};
}
}
现在,如果我想找到数字的逆模数,例如13,其中mod是例如1000007,那么我只需通过
调用此函数pair<int, int> res = extendedEuclidean(13, 1000007);
然后结果是
res.first
我的问题是为什么以及在这次递归中究竟发生了什么?以及为什么它会产生正确的结果。
N.B:这里gcd(a,b)必须是1.
答案 0 :(得分:4)
欧几里得算法计算一对数(a, b)
的最大公约数(假设为a>b
)。它使用的观察结果是a
和b
的任何公约数也是a-b
的除数。原因如下:
让d
成为除数。然后,对于整数a
,a=d*k
可以表示为k
,对于整数b=d*l
,l
可以表示为a-b=d*k-d*l=d*(k-l)
。然后,k-l
。 d
也是一个整数。因此,a-b
必须是a%b
的除数。
算法的作用是尽可能多地从较大的数字中减去较小的数字。这是a = 25
部分。例如。如果b = 7
和a%b=4
,b
是从a
减去a
3次后得到的结果。之后,新的b
将小于extendedEuclidean(b, a%b);
。因此,您交换两个数字。这是您调用递归的部分:x
扩展的欧几里德算法做得更多。此外,它会计算两个数字y
和gcd(a, b) = x * a + y * b
,例如a'=gcd
。以下是它的完成方式:
在上一次迭代中,您最终得到b'=0
和gcd=a' * 1 + b' * 0
。因此,您有1
,其中0
和x'
分别为y'
和a''
。假设前一次迭代中的值为b''
和a'=b''
。然后我们知道b'=a'' % b''
和b'=a''-(a''/b'')*b''
。有了这个,我们发现gcd = a' * x' + b' * y'
gcd = b'' * x' + (a''-(a''/b'')*b'') * y'
= a'' * y' + b'' * (x' - y' * (a''/b''))
(尽可能经常减去)。我们可以修改
x''=y'
因此,新的y''=x' - y' * (a''/b'')
和return {d.y, d.x - (d.y*(a/b))};
。这是您的退货声明a=25, b=7
。
一个例子:
让a
。第一遍计算列b
和x
(从上到下)。这解释了递归调用。第二遍计算列y
和 a | b | x | y | means
----+--------------+------------------------------+---------------------
25 | 7 | 2 | -1 - 2 * (25/7) = -7 | 1 = 2 * 25 - 7 * 7
7 | 25 % 7 = 4 | -1 | 1 + 1 * (7/4) = 2 | 1 = (-1) * 7 + 2 * 4
4 | 7 % 4 = 3 | 1 | 0 - 1 * (4/3) = -1 | 1 = 1 * 3 - 1 * 3
3 | 4 % 3 = 1 | 0 | 1 - 0 * (3/1) = 1 | 1 = 0 * 3 + 1 * 1
1 | 3 % 1 = 0 | 1 | 0 | 1 = 1 * 1 + 0 * 0
(从下到上)。这说明了退货声明:
1 = 2 * 25 - 7 * 7
所以你得到2
其中.first
的结果是-7
而.second
的结果是mod 25
。如果我们在1 == 2 * 0 - 7 * 7
1 == -7 * 7
,则会缩减为:
-7 == 18
因此,result.second
(7 (mod 25)
)是result.first
的乘法逆。请注意,我交换了输入以避免不必要的第一次迭代。否则,它是<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/common_actionbar" />
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
。