- 利用扩展欧几里得定理计算乘法逆元。理解并掌握中国剩余定理。
实现本次实验所用的环境为jdk1.8下的Java代码,代码测试结果在最下面。
由于扩展欧几里得定理和中国剩余定理都要基于求最大公因数的方法getGcd(),这里附上相关代码:
public static int getGcd(int a,int b){ int gcd = 1; if (a < b){ //若传入a小于b,交换a和b的值(不用定义一个新变量,节省空间) a = a + b; b = a - b; a = a - b; } if (a % b == 0){ //如果a mod b为0,则b为最大公约数 gcd = b; } while (a % b > 0){ a = a % b; if (a < b) { a = a + b; b = a - b; a = a - b; } if (a % b == 0) { gcd = b; } } return gcd; }
扩展欧几里得定理的实现方法(函数)inverse():
public static int inverse(int p,int a) { int[] m = {1,0,p}; int[] n = {0,1,a}; 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]; } if(n[2] == 1) { if(n[1] < 0) { n[1] = n[1] + p; } return n[1]; } if(n[2] == 0){ flag = false;//无逆元,跳出循环 } } return 0; }
中国剩余定理实现方法(函数)CRT():
public static int CRT(int[] m,int[] a){ int A = 0; int M = 1; int[] m1 = new int[m.length];//存放m的乘法逆元 int[] m2 = new int[m.length]; for (int i = 0;i < m.length;i++){ M *= m[i]; m2[i] = m[i];//复制一个mi数组 } for (int i = 0;i < m.length;i++){ m[i] = M / m[i]; m1[i] = inverse(m2[i],m[i]);//求出m[i]的逆元 A += a[i] * m[i] * m1[i]; } return A % M; }
测试方法:放在主方法 main() 中测试
//main方法 public static void main(String[] args) { //验证getGcd方法 System.out.println(getGcd(24140,16762));//34 //验证扩展欧几里得算法 System.out.println(inverse(49,37));//37的乘法逆元:4 System.out.println(inverse(37,49));//49的乘法逆元:34 //验证中国剩余定理 int[] a = {11,42}; int[] m = {37,49}; System.out.println(CRT(m, a));//973 }实验结论
通过本次实验,我对使用扩展欧几里得定理求逆元的原理有了更进一步的理解并且能对其加以运用,同时也更深刻认识到了中国剩余定理的原理与运用,学习到了利用中国剩余定理求一次同余方程组的解,除此之外,也使我对Java语言的使用更加熟练。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)