Java递归子串搜索实现求助(禁用contains()方法)
嘿,我瞅了下你写的递归版myContains代码,发现几个关键问题导致它没法正确工作,咱们一步步来修正~
原代码的核心问题
- 永远不会返回true:你只写了递归截取主串的逻辑,但完全没检查当前主串的开头是否和子串匹配,程序只会一直递归到主串为空,最后返回false
- 缺失关键终止条件:当主串的长度已经小于子串长度时,根本不可能匹配成功,这时候应该直接终止递归返回false
- 空值/空串处理不够严谨:原判断里没考虑子串比主串长的情况,比如主串是"abc",子串是"abcd",这时候直接返回false就好
修正后的递归实现
下面是修复后的代码,我分两种写法:一种是用startsWith简化判断(如果允许的话),另一种是完全手动比较字符,避免用任何内置的匹配方法:
写法1:使用startsWith简化判断
public boolean myContains(String s1, String s2) { // 前置校验:空值、空串、子串比主串长,直接返回false if (s1 == null || s2 == null || s1.isEmpty() || s2.isEmpty() || s1.length() < s2.length()) { return false; } // 检查当前主串开头是否完全匹配子串 if (s1.startsWith(s2)) { return true; } // 递归:截取主串从第1个字符开始的子串,继续匹配 return myContains(s1.substring(1), s2); }
写法2:完全手动比较字符(避免使用内置匹配方法)
如果连startsWith也不想用,咱们可以手动遍历字符判断开头是否匹配:
public boolean myContains(String s1, String s2) { // 前置校验逻辑和上面一致 if (s1 == null || s2 == null || s1.isEmpty() || s2.isEmpty() || s1.length() < s2.length()) { return false; } // 手动检查主串开头的s2.length()个字符是否和s2一致 boolean isMatch = true; for (int i = 0; i < s2.length(); i++) { if (s1.charAt(i) != s2.charAt(i)) { isMatch = false; break; } } if (isMatch) { return true; } // 递归继续判断主串的剩余部分 return myContains(s1.substring(1), s2); }
递归逻辑说明
- 前置校验:先把所有不可能匹配的情况直接过滤,避免无效递归
- 匹配判断:每次递归先检查当前主串的开头是否和子串完全一致,一致就直接返回true
- 递归推进:如果开头不匹配,就把主串从第1个字符开始截取,继续递归判断剩余部分
这样就能正确实现你要的“判断子串是否存在于主串”的功能啦~
内容的提问来源于stack exchange,提问作者Gustavo
相关产品推荐
相关产品推荐

