JAVA實現輾轉相除法 歐幾里得演算法求逆
乘法逆元定義:
一般來講,如果要運算加法、減法、乘法、乘方,都應該滿足以下式子:
(a+b)%c=(a%c+b%c)%c(a+b)%c=(a%c+b%c)%c
(a−b)%c=(a%c−b%c)%c(a−b)%c=(a%c−b%c)%c
(a⋅b)%c=(a%c⋅b%c)%c(a·b)%c=(a%c·b%c)%c
ab%p=(a%p)b%pab%p=(a%p)b%p
然而這裡出現了一個問題:
如果是除法,並不滿足(a/b)%c=(a%c/b%c)%c(a/b)%c=(a%c/b%c)%c,不信你代個數試試:
(6/3)%3=2≠(6%3/3%3)%3=RuntimeError(6/3)%3=2≠(6%3/3%3)%3=RuntimeError
那怎麼實現對除法的取餘呢?
這裡就引入乘法逆元這個東西。
他可以達到這樣的效果:
(a/b)%k=(a⋅c)%k(a/b)%k=(a·c)%k
你可以將它簡單地理解為類似於倒數的東西,只不過是再對倒數取餘而已,即:
(b⋅c)%k=1(b·c)%k=1
所以注意,逆元是針對一個數而言的,並不是針對一個表示式。
求法
使用擴充套件歐幾里德演算法,但是好像只能在所求的數和取餘的數互質才行。
因為:
(b⋅c)%k=1(b·c)%k=1
所以我們可以得到
b⋅c+n⋅k=1b·c+n·k=1
所以只有在bb和kk互質的情況下,才能得到:
b⋅c+n⋅k=gcd(b,k)b·c+n·k=gcd(b,k)
然後用這個方程求解出cc的值,就是所求的乘法逆元。
求79關於3220的乘法逆元:
執行結果:
附錄:
java實現:
package oujilide;
public class ojld {
public static int niyuan(int a,int b) //求79關於模3220的乘法逆元
{
int[] m={1,0,a};
int
int[] temp=new int[3];
int q=0; //初始化
boolean flag=true;
while(flag)
{
q=m[2]/n[2];
for(int i=0;i<3;i++)
{
temp[i]=m[i]-q*n[i];
m[i]=n[i];
n[i]=temp[i];
System.out.print(temp[i]+" ");
}
System.out.println();
if(n[2]==1)
{
if(n[1]<0)
n[1]=n[1]+a;
return n[1];
}
if(n[2]==0)
flag=false;
}
return 0;
}
public static void main(String[] args) {
int result = niyuan(3220,79);
System.out.println();
System.out.println("79關於3220的逆元為:"+result);
}
}