【牛客网刷题】
求解立方根
题目描述
•计算一个数字的立方根,不使用库函数
详细描述:
•接口说明
原型:
public static double getCubeRoot(double input)
输入:double 待求解参数
返回值:double 输入参数的立方根,保留一位小数
输入描述:
待求解参数 double类型
输出描述:
输入参数的立方根 也是double类型
示例
输入:
216
输出:
6.0
解题思路
牛顿迭代法:
参考这篇非常容易理解的方法
事实上,牛顿迭代法不仅可以用来求立方根、平方根,求解大多数多项式的零点都可以用它来求。
求平方根、立方根用牛顿迭代法是安全的,没有越来越远离的不收敛、循环震荡的不收敛、不能完整求出所有的根等问题。
求a的立方根,就是要求f(x)=x3-a=0的解。
一般,选取x0=a/2,y0=f(x0)作为初始点,从这点做切线,取切线的零点x’;再从x1=x’,y1=f(x1)做切线,…,直到xn+1-xn<误差。
切线方程:f(xn+1)=f’(xn)(x-xn)+f(xn)
转化为:f(xn+1)=3xn2(x-xn)+xn3-a
它的零点是:xn+1=(a-xn3)/3xn2+xn=a/(3xn2)-(2xn)/3
我的代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
double input=sc.nextInt();
System.out.println(getCubeRoot(input));
}
public static double getCubeRoot(double input){
double a0=input/2;
double res=0;
while(input-res*res*res>0.1||input-res*res*res<-0.1){//控制误差
res=input/(3*a0*a0)+2*a0/3;
a0=res;
}
res = Double.valueOf(String.format("%.1f", res));
return res;
}
}
开始的误差设置的是1:
while(input-res*res*res>1||input-res*res*res<-1)
但是不能通过所有的测试用例,于是调小为:
while(input-res*res*res>0.1||input-res*res*res<-0.1)
另外截取字符串到小数点后一位的方法是String.format("%.1f", res)。
通过这道题对牛顿迭代法有了新的认识~
/
/
/
不过这道题的标签竟然是二分。。。这很尴尬,我还专门去搜索学习了getCubeRoot就是用牛顿迭代法实现的。。。