You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
}

递归逻辑说明

  1. 前置校验:先把所有不可能匹配的情况直接过滤,避免无效递归
  2. 匹配判断:每次递归先检查当前主串的开头是否和子串完全一致,一致就直接返回true
  3. 递归推进:如果开头不匹配,就把主串从第1个字符开始截取,继续递归判断剩余部分

这样就能正确实现你要的“判断子串是否存在于主串”的功能啦~

内容的提问来源于stack exchange,提问作者Gustavo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:02:27