算法1.1 最大公约数(欧几里得)&判定素数&计算平方根(牛顿迭代法)

来源:互联网 发布:centos gcc 升级 编辑:程序博客网 时间:2024/04/30 15:37
 最近在看Robert Sedgewick和Kevin Wayne的《算法》,顺便学学Java,边看边查资料总结一些有用的东西

  1. 欧几里得算法:求最大公约数
  2. 判定素数
  3. 牛顿迭代法:计算平方根

1.欧几里得算法:求最大公约数
比较辗转相除法与更相减损术的区别
  1. 都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时,计算次数的区别较明显。
  2. 从结果体现形式来看,辗转相除法体现结果是以相除余数为0则得到,而更相减损术则以减数与差相等而得到
欧几里得算法:
  • 判断p、q是否为非负
  • 如果有一个为0,最大公约数为另一个
  • 辗转相除直至余数为0
public class GreatestCommonDivisor {    public static int  GCD (int p,int q){        if(p<0 || q<0)            return -1;        if(p < q){ //make sure p>q            int temp = p;            p = q;            q = temp;        }        while (q != 0) {            int remainder =p%q;            p = q;            q = remainder;        }        return p;    }    public static void main(String []args){        System.out.printf("20,8: %d\n",GCD(20,8));System.out.printf("20,35: %d\n",GCD(20, 35));        System.out.printf("0,10: %d\n",GCD(0,10));        System.out.printf("-5,10: %d\n",GCD(-5,10));    }}
2.判定素数
素数定义:
  • “素数”,又称“质数”,是指: 除1和其自身之外,没有其它约数的正整数 如 2,3,5,7,11,13,17,19,23,... 
  •  2是最小的质数,也是唯一的偶质数 
  •  质数有无数多个 与素数相对的,有“合数”: 除1和其自身之外,仍有其它约数的正整数
  •  规定:1既不是质数,也不是合数
定理:如果一个数不是素数而是合数, 那么一定可以由两个自然数相乘得到, 其中一个≥它的平方根,另一个≤它的平方根。并且成对出现,所以循环查找的终止条件为 i*i<N
public class IsPrime {public static boolean isPrime(int N){if(N < 2) return false;for(int i=2;i*i<N;++i) //attention to the terminal conditionif(N % i == 0) return false;return true;}public static void main(String []args){ if(isPrime(17))System.out.println("是素数");elseSystem.out.println("是合数");}}
3.计算平方根(牛顿迭代法)
牛顿迭代法Newton's method):是近似求解方程的方法。其原理是用(x,f(x))的切线与x轴的交点,不断逼近f(x) = 0时的根x 
以计算平方根为例:
  • f(x) = x² - C,x为C的平方根,f(x)求导为2x,f(x) = 0的根为C/x
  • 代入下面的公式:【X(n+1) = x -(x²-C)/2x】  => 【X(n+1) = x -(x-C/x)/2=> 【X(n+1) = (x+C/x)/2
  • 迭代的终止条件为:abs( X(n+1) - C/X(n+1) ) ≤ error*x
举一反三:计算三次方根:
  •  f(x) = x^3 - C ,x为C的三次方根,f(x)求导为3x²,f(x) = 0的根为C/x²
  • 代入下面的公式:【X(n+1) = x -(x^3-C)/3x²】  => 【X(n+1) = x -(x-C/x²)/3】=> 【X(n+1) = (2x+C/x²)/3】
  • 迭代的终止条件为:abs( X(n+1) - C/X²(n+1) ) ≤ error*x
 ==>令y=0得到 
声明:以下两张图片取自Wiki:
public class SqrtNewtonMethod {    public static double  Sqrt (double C){        if(C < 0) return Double.NaN;        double error = 1e-15; //Approximate Root until less than error        double x = C; //Suppose any one root        while(Math.abs(x-C/x) > error * x) //until ≤ error            x = (x+C/x)/2.0; //Approximate        return x;    }    public  static  double CubeRoot(double C){        if(C < 0) return Double.NaN;        double error = 1e-15; //Approximate Root until less than error        double x = C; //Suppose any one root        while (Math.abs(x-C/(x*x)) > error*x)            x = (2*x+C/(x*x))/3;        return x;    }    public static void main(String []args){        System.out.printf("4.0的平方根:%f\n",Sqrt(4));        System.out.printf("2.0的平方根:%f\n",Sqrt(2.0));        System.out.printf("1.0的平方根:%f\n",Sqrt(1));        System.out.printf("0.0的平方根:%f\n",Sqrt(0.0));        System.out.printf("-1.0的平方根:%f\n",Sqrt(-1.0));        System.out.printf("64的三次方根:%f\n",CubeRoot(64));        System.out.printf("8.0的三次方根:%f\n",CubeRoot(8));        System.out.printf("2.0的三次方根:%f\n",CubeRoot(2.0));        System.out.printf("1.0的三次方根:%f\n",Sqrt(1.0));        System.out.printf("0.0的三次方根:%f\n",Sqrt(0));        System.out.printf("-1的三次方根:%f\n",Sqrt(-1));    }}





0 0