基于递归函数生成指定字符串的合法IP地址:代码调试求助
问题分析与修复方案
你的代码主要存在参数设计混乱、合法性判断缺失、递归逻辑错误这几个核心问题,导致无法正确生成合法IP地址。我们先拆解原代码的错误点,再给出正确的实现:
原代码的关键错误
- 冗余且错误的参数传递:
endIndex和strNum完全没必要作为递归参数,而且递归时的字符串截取逻辑s.substring(i,startIndex + endIndex)完全错误,会导致截取的片段混乱。 - IP段合法性判断缺失:没有处理前导零的情况(比如
"01"是非法IP段,只有单个"0"是合法的),且判断数值范围的时机错误,导致非法片段被加入组合。 - 递归终止与循环逻辑混乱:
- 终止条件判断顺序错误,应该先检查是否已经选满4段,再验证是否用完了整个字符串。
- 循环遍历范围错误,IP段最多只能是3位,不需要遍历到字符串末尾,只需要从当前索引尝试截取1-3位即可。
- 回溯逻辑错误:
combination.add和remove的时机不对,导致回溯时无法正确撤销选择。
正确的递归实现代码
以下是修复后的Java代码,完全符合你的需求:
import java.util.ArrayList; import java.util.List; public class IpRestorer { public static void main(String[] args) { String s = "25525511135"; List<List<String>> results = new ArrayList<>(); restoreIp(s, results, new ArrayList<>(), 0, 0); // 打印结果,和预期一致 System.out.println(results); } private static void restoreIp(String s, List<List<String>> results, List<String> current, int start, int segments) { // 终止条件:选了4段,且刚好用完整个字符串 if (segments == 4) { if (start == s.length()) { results.add(new ArrayList<>(current)); } return; } // 尝试截取1-3位作为当前IP段(最多3位,且不能超过字符串长度) for (int i = start; i < start + 3 && i < s.length(); i++) { String segment = s.substring(start, i + 1); // 检查IP段合法性: // 1. 数值在0-255之间 // 2. 没有前导零(除非是单个"0") if (isValidSegment(segment)) { current.add(segment); // 递归:下一段从i+1开始,段数+1 restoreIp(s, results, current, i + 1, segments + 1); // 回溯:撤销当前选择 current.remove(current.size() - 1); } } } private static boolean isValidSegment(String segment) { // 长度超过3直接非法 if (segment.length() > 3) { return false; } // 前导零的情况:长度>1且以0开头,非法 if (segment.length() > 1 && segment.startsWith("0")) { return false; } // 转换为数字检查范围 int num = Integer.parseInt(segment); return num >= 0 && num <= 255; } }
代码逻辑说明
- 递归参数:
start:当前截取IP段的起始索引segments:已经选好的IP段数量(最多4段)
- 终止条件:当选满4段时,只有当
start等于字符串长度(说明刚好把所有字符用完),才将当前组合加入结果。 - 循环逻辑:每次从
start开始,尝试截取1-3位字符(因为IP段最多3位),避免无效遍历。 - 合法性校验:单独提取
isValidSegment方法,清晰判断IP段是否合法,重点处理前导零的情况。 - 回溯操作:加入当前合法段后递归,递归返回后移除该段,恢复状态以尝试下一种可能。
运行这段代码后,你会得到预期的结果:[["255","255","11","135"], ["255","255","111","35"]]
内容的提问来源于stack exchange,提问作者Abdusoli




