我正在研究一种计算数字乘法逆的算法。我必须做一个功能来做到这一点。但是,我坚持优化。
我的算法有效,但只适用于相对较小的数字。
鉴于3个数字(a,b,n)
,我需要返回a/b (mod n)
。
这部分我能做到。但是,当n
非常大时,我的代码变得非常慢,因为我正在以这种方式解决它:
for i in range(1,n):
if b*i%n == a%n:
return i
我的问题是n
的大小。如果它变得很大,代码就不会运行。
现在,假设我的数字是3,2,7
,我需要在不检查所有数字的情况下获得答案5
。所以我尝试使用扩展的欧几里德算法。
这就是我所做的:
ax + by = 1
ax = 1 (mod n) => ax - 1 = qn, where q is an integer
我最终得到了等式:
ax - qn = 1
如果我总结我的数字,我最终得到:
3x + 7q = 1
我该如何解决这个问题?还有更好的方法吗?
答案 0 :(得分:1)
你想要解决的是丢番图方程式
ax+by=1
其中所有数字都是整数。要解决这样的问题,您需要(如标题所示)扩展的欧几里德算法,该算法最好使用表格进行解释。首先,你做正常的欧几里德算法:
a b q
3 7 0
7 3 2
3 1 3
1 0
新的a由a-b*q
计算,q是a/b
的商。然后从底部开始向上计算从x=1 y=0
开始计算x和y。在每个步骤中,新的x是旧的y,新的y是x old -q * y old 。为了证明这一点(不幸的是我无法更好地格式化):
a b q x y
3 7 0
7 3 2
3 1 3
1 0 1 0
a b q x y
3 7 0 -2 0 // 1-0*(-2)
7 3 2 1 -2 // 0-2*1
3 1 3 0 1 // 1-3*0
1 0 1 0
3*(-2)+7*1=1
3*(-2)=1 (mod 7) | +7
-2=5 (mod 7)
因此,当您填写表格或自己的实施时,您在x字段中得到了答案,即使在这种情况下它可能是负数,您也必须一次添加N.