到目前为止,这是我的代码:
def mod_div(a, b, n):
if gcd(b,n) != 1:
return 'Undefined'
for x in range(1, n):
if b*x%n == a%n:
return x
这段代码接受我制作的函数gcd()并返回gcd,然后我用它来计算逆。我搜索了这些问题,但似乎没有人给我正确答案。
我的问题是:当我执行div_mod(3,2,7)时,代码返回5,应该如此。但是,当我为大数字时,例如n> 10000,计算解决方案需要很长时间,因为通过n的迭代来找到正确的数字。
我试着查看其他问题,并且在他们的答案中,他们都有类似的事情,但是如果gcd!= 1,他们都会返回x%n而不是i中的i。 这对我没有帮助,也没有给出正确答案。
例如。如果我使用a = 12,b = 3和n = 11它应该返回4,但除了我的所有函数都返回1。
我想知道是否有更有效的方法来使用eulids扩展定理,而不是测试每个n,并希望有效。
答案 0 :(得分:5)
扩展欧几里德算法解决了这个问题,你说得对。但是,您无需将其称为n
次 - 您只需要一次。查看http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
这是来自http://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm
的命令式python算法def egcd(a, b):
x,y, u,v = 0,1, 1,0
while a != 0:
q, r = b//a, b%a
m, n = x-u*q, y-v*q
b,a, x,y, u,v = a,r, u,v, m,n
return b, x, y
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
return None # modular inverse does not exist
else:
return x % m
O(1)空间和最坏情况下的O(log n)时间。
现在,除了模n
之外,我们按照定义
def moddiv(a, b, n):
binv = modinv(b, n)
if not binv:
return None
return a * binv % n