如何在jGRASP的Java程序中实现无循环无Math.sqrt的递归平方根函数?
递归实现平方根的Java解决方案
问题背景
这是一项大学编程作业,要求在jGRASP环境下编写Java程序,使用递归实现平方根计算,禁止使用while/for循环及Math.sqrt()方法。已成功实现平方递归函数powS,但多次修改powNS方法均失败:
- 调用
powS的版本逻辑错误,本质仍在计算平方 - 除法实现的版本逻辑混乱,存在报错风险
- 另一版本因整数除法逻辑错误,计算结果完全偏离预期
尝试的错误代码
首次尝试(逻辑错误)
import java.util.Scanner; public class SquareRoot { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("Enter a number: "); int x = scanner.nextInt(); System.out.println("Enter a number: "); int y = scanner.nextInt(); System.out.println("" + powS(x)); System.out.println("" + powNS(y)); } public static int powS(int x) { int result = (2 * x) - 1; if (x == 0) { return 0; } return result + powS(x-1); } public static int powNS(int y) { int solution = (2 * y) - 1; if (y == 0) { return 0; } return solution + powS(y-1); } }
报错的尝试(逻辑混乱)
import java.util.Scanner; public class SquareRoot9 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("Enter a number: "); int x = scanner.nextInt(); System.out.println("Enter a number: "); int y = scanner.nextInt(); System.out.println("" + powS(x)); System.out.println("" + powNS(y)); } public static int powS(int x) { int result = 2 * (x-1); if (x == 0) { return 0; } return result * powS(x-1); } public static int powNS(int y) { int solution = 2 * (y-1); if (y == 0) { return 1; } if (y == 1) { return solution; } return solution / powNS(y-1); } }
结果错误的尝试(整数除法错误)
import java.util.Scanner; public class SquareRoot10 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("Enter a number: "); int x = scanner.nextInt(); System.out.println("Enter a number: "); int y = scanner.nextInt(); System.out.println("" + powS(x)); System.out.println("" + powNS(y)); } public static int powS(int x) { int result = (2 * x) - 1; if (x == 0) { return 0; } return result + powS(x-1); } public static int powNS(int y) { int solution = (2 / y) - 1; if (y == 0) { return 0; } return solution + powS(y-1); } }
正确实现方案
核心思路
采用二分查找递归法实现整数平方根计算:在区间[1, n]中递归查找最大的整数mid,使得mid² ≤ n(或精确等于n)。直接复用你已正确实现的powS函数计算平方,符合作业要求。
完整可运行代码
import java.util.Scanner; public class SquareRoot { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("输入一个数计算平方: "); int x = scanner.nextInt(); System.out.println("输入一个数计算平方根: "); int y = scanner.nextInt(); System.out.println(x + " 的平方是: " + powS(x)); // 处理0的特殊情况 if (y == 0) { System.out.println(y + " 的平方根是: 0"); } else { System.out.println(y + " 的整数平方根是: " + powNS(y, 1, y)); } scanner.close(); } // 已验证正确的平方递归函数 public static int powS(int x) { if (x == 0) { return 0; } return (2 * x - 1) + powS(x - 1); } // 递归二分查找计算整数平方根,low和high为查找区间边界 public static int powNS(int n, int low, int high) { // 递归终止条件:区间左边界超过右边界,返回右边界(最大符合条件的数) if (low > high) { return high; } int mid = low + (high - low) / 2; // 避免整数溢出 int midSquared = powS(mid); // 复用已有平方函数 if (midSquared == n) { // 找到精确平方根 return mid; } else if (midSquared > n) { // 中间值平方过大,缩小到左半区间查找 return powNS(n, low, mid - 1); } else { // 中间值平方过小,扩大到右半区间查找 return powNS(n, mid + 1, high); } } }
代码说明
- 辅助参数设计:
powNS增加low和high参数定义二分查找区间,是递归实现二分查找的标准方式 - 复用已有函数:直接调用你写的
powS计算平方,无需重复实现平方逻辑 - 终止条件处理:当查找区间失效时,返回右边界,得到最大的满足
mid² ≤ n的整数 - 特殊情况兼容:单独处理输入为0的场景,避免递归区间出现异常
测试示例
- 输入x=5,输出
5 的平方是: 25 - 输入y=25,输出
25 的整数平方根是: 5 - 输入y=26,输出
26 的整数平方根是: 5(因为5²=25≤26,6²=36>26)
可选:浮点数精确平方根实现
如果需要计算高精度的浮点数平方根,可以采用牛顿迭代递归法:
// 计算浮点数平方根,guess为初始猜测值 public static double powNS(double n, double guess) { // 精度控制,差值小于1e-6时终止递归 if (Math.abs(guess * guess - n) < 1e-6) { return guess; } // 牛顿迭代公式:新猜测值 = (当前猜测值 + n/当前猜测值) / 2 double newGuess = (guess + n / guess) / 2; return powNS(n, newGuess); }
调用时可传入n/2作为初始猜测值,例如powNS(26, 13.0)会返回约5.099的精确值。
内容的提问来源于stack exchange,提问作者RWorker
相关产品推荐
相关产品推荐

