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

Go实现首个子串匹配函数时for循环提前终止导致结果错误的问题求助

Go实现首个子串匹配函数时for循环提前终止导致结果错误的问题求助

我来帮你分析下问题出在哪,你的代码核心问题是循环结构写错了,导致还没处理到正确的起始位置,循环就提前跑完了,直接返回了-1。

先看你写的for循环:

for range len(haystacks) - len(needles) + 1 {
    // ... 匹配逻辑
}

这种写法是让循环执行固定的len(haystacks)-len(needles)+1次,但你在循环体里还会手动修改slow变量,这就把循环次数和slow的取值完全搞脱节了。比如你的测试用例里,len(haystacks)-len(needles)+1等于7,循环会执行7次,但每次匹配失败slow都会自增,等循环次数耗尽时,可能还没轮到处理slow=4这个正确位置,就直接触发了最后的return -1。

正确的暴力匹配逻辑应该是让slow从0遍历到len(haystacks)-len(needles),每个slow对应一个子串的起始位置,而不是机械地执行固定次数的循环。你现在的写法要么会跳过某些起始位置,要么会在没处理完有效位置时就提前结束循环。

另外提一句,你把haystack和needle转换成[]rune其实是多余的(测试用例都是ASCII字符,字符串索引和rune索引完全一致),还会多占内存,但这不是当前问题的根源。

给你两种修复方案,选哪个都行:

方案一:修正循环结构,手动控制slow的遍历范围

把你的for循环改成基于slow的范围循环,确保每个可能的起始位置都被处理到:

func strStr(haystack string, needle string) int {
    n, m := len(haystack), len(needle)
    if m > n {
        return -1
    }
    slow := 0
    fast := 0
    // 让slow遍历所有合法的起始位置
    for slow <= n - m {
        if haystack[slow+fast] == needle[fast] {
            fast++
        } else {
            slow++
            fast = 0
        }
        if fast == m {
            return slow
        }
    }
    return -1
}

方案二:更清晰的暴力匹配实现(推荐)

把每个起始位置的匹配逻辑独立出来,代码可读性更高,也不容易出逻辑漏洞:

func strStr(haystack string, needle string) int {
    n, m := len(haystack), len(needle)
    if m == 0 {
        return 0
    }
    if m > n {
        return -1
    }
    // 遍历所有可能的起始位置
    for i := 0; i <= n - m; i++ {
        j := 0
        // 检查从i开始的子串是否完全匹配
        for j < m && haystack[i+j] == needle[j] {
            j++
        }
        if j == m {
            return i
        }
    }
    return -1
}

至于你debug时看到在slow=3时返回-1,本质是因为固定次数的循环在执行到第4次时,已经耗尽了有效迭代机会,还没来得及处理slow=4这个正确位置,就直接走到了函数末尾的return -1。只要把循环改成基于slow的范围遍历,就能保证不会错过正确的起始位置。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:54:31