首先我承认,我没有很好的算法分析能力,最近被几道看似简单却包含着一些算法的题目搞得心情很不爽,但回过头想想,只因笔下功夫太少,递归可能是算法中稍微抽象点的形式,看似几行短短的代码,却能够在一些问题上扮演举足轻重的角色,下面我参考了开发者头条上考察一个软件开发者编程思维的题目,大致是这样的:
给出一个方法签名sqrt(),要求结果是16的开平方并且误差范围在±0.5之间的数,当然,这里我只是举个栗子,要求输入的数值和误差是随意但满足要求的(你不能对一个负数开平方),如下:
sqrt(16,0.5)
返回的结果只要是在[3.5,4.5]之间都可以。
希望大家能够自己尝试着去做一下,给点提示:二分法+递归,当然别的更好的方法也欢迎。
答案(仅为个人想法):
package jsoup;
public class SqrtDemo {
public static void main(String[] args){
int count =0;
while(count<100){
sqrt(16, 0.5);
count++;
}
}
public static void sqrt(int input, Double error){
sqrt(0, input, input, error);
}
public static void sqrt(int begin, int end, int input,Double error){
if(end<0){System.out.println("负数");
} else {
int mid = (begin + end)/2;
if(mid*mid<input)
sqrt(mid, end, input,error);
if(mid*mid>input)
sqrt(begin, mid, input,error);
else if(mid*mid == input){
double left = mid-error;
double index = Math.random()*2*error + left;
System.out.println(index);
}
}
}
}
在这里我尝试了100次的计算结果
昨晚做完这道题,和室友一讨论,才发现一个即幼稚又致命的错误,当要求开方的值是一个不能整开的数值时比如3,那就完蛋了,stackoverflowerror,天,以前都是听说过这个家伙 ,这次是真真切切体验了一把。经过和小伙伴的讨论,把以上的代码稍作修改,就可以求任何大于零的开根方的值了。
package jsoup;
public class SqrtDemo {
public static void main(String[] args){
System.out.println(Math.sqrt(3));
sqrt(3.0, 0.00000001);
}
public static void sqrt(Double input, Double error){
sqrt(0.0, input, input, error);
}
public static void sqrt(Double begin, Double end, Double input,Double error){
if(end<0){System.out.println("负数");
} else {
Double mid = (double) ((begin + end)/2);
if(mid*mid<input)
if(end-mid<=error){ // 此处为修改的核心部分,当包含目标值(这里是根号下3)的左右界差值在error范围内时,左右界的均值肯定满足在目标值±error范围内
System.out.println((end+mid)/2);
}
else
sqrt(mid, end, input,error);
if(mid*mid>input)
sqrt(begin, mid, input,error);
else if(mid*mid == input){
double left = mid-error;
double index = Math.random()*2*error + left;
System.out.println(index);
}
}
}
}
20170101更新,新年的第一天,希望在以后编程的道路上越走越顺利