看下下面这道题:
在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
public class ArithmeticTest {
/**
* 在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
*/
public static void main(String[] args) {
}
}
这题一共两种解法,分别是二分查找和牛顿迭代,老规矩先理思路.
二分查找
编码如下
public class ArithmeticTest {
/**
* 在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
*/
public static void main(String[] args) {
int x = 37;
int result = binarySearch(x);
System.out.println("结果为:" + result);
}
private static int binarySearch(int x) {
//为什么指针要从-1开始? 因为 0 和1 都可能是返回值
int index = -1;
int left = 0;
int right = x;
//什么时候跳出循环? left右移,right左移,当两个指针相撞时,循环结束
while (left <= right) {
//二分位置的值
int mid = left + (right - left) / 2;
if (mid * mid <= x) {
//当中间值的平方小于等于x时,指针右移
index = mid;
left = mid + 1;
} else {
//反过来right左移
right = mid - 1;
}
}
return index;
}
}
输出结果:
牛顿迭代
还是直接看编码吧.
public class ArithmeticTest {
/**
* 在不使用 sqrt(x)函数的前提下,得到x 的平方根的整数部分.例:输入30,输出5 输入37 输出6
*/
public static void main(String[] args) {
int x = 37;
int result = newTon(x);
System.out.println("结果为:" + result);
}
//牛顿迭代
private static int newTon(int x) {
//等于0直接返回,否则算法会报错
if (x == 0) {
return 0;
}
//x/2 这个值 随便传 传x也可以,不过为了减少递归次数,最好给个近似值
return (int) sqrt(x / 2, x);
}
private static double sqrt(double i, int x) {
// 声明结果
double result = (i + x / i) / 2;
// 运算到 double精度极限就可以返回
if (result == i) {
return i;
} else {
//递归
return sqrt(result, x);
}
}
private static int binarySearch(int x) {
//为什么指针要从-1开始? 因为 0 和1 都可能是返回值
int index = -1;
int left = 0;
int right = x;
//什么时候跳出循环? left右移,right左移,当两个指针相撞时,循环结束
while (left <= right) {
//二分位置的值
int mid = left + (right - left) / 2;
if (mid * mid <= x) {
//当中间值的平方小于等于x时,指针右移
index = mid;
left = mid + 1;
} else {
//反过来right左移
right = mid - 1;
}
}
return index;
}
}
打印结果