您的位置:首页 > 其它

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

2016-04-10 14:11 309 查看
最近在看Robert Sedgewick和Kevin Wayne的《算法》,顺便学学Java,边看边查资料总结一些有用的东西

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

1.欧几里得算法:求最大公约数

比较辗转相除法与更相减损术的区别

都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时,计算次数的区别较明显。
从结果体现形式来看,辗转相除法体现结果是以相除余数为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 condition
if(N % i == 0) return false;
return true;
}
public static void main(String []args){
if(isPrime(17))
System.out.println("是素数");
else
System.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));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: