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

判断字符串是否为另一串子序列的Python代码Bug排查

问题描述

给定两个字符串M和W,需要判断其中一个字符串是否是另一个的子序列。
我编写了如下实现代码,但在编程评测站点的部分未知测试用例上运行不通过,所有我能想到的测试场景都验证过返回正确,找不到问题点:

def filterr(bigStr,smallStr,i):
res=''
for char in bigStr:
    if(char in smallStr[i:]):
        i+=1
        res+=char
return res

m,w=input().split()
if(m==w):
    print('YES')
else:
    if(len(m)<len(w)):
        m,w=w,m
    s=filterr(m,w,0)
    if(s==w): print('YES')
    else: print('NO')
已测试通过用例
  • 输入:john johanna,输出:YES
  • 输入:ira ira,输出:YES
  • 输入:kayla jayla,输出:NO
错误根因

代码的匹配逻辑存在本质缺陷。
filterr函数判断匹配的规则是:只要当前遍历到的长串字符,在短串当前位置往后的子串里存在,就算匹配成功,直接移动短串指针、把字符拼到结果里。这个逻辑完全没遵守子序列「按顺序逐字符匹配」的核心要求——只要字符在短串后续部分存在就提前占用匹配位,直接跳过短串里本来该优先匹配的字符,最后结果串和原短串无法对齐,就会把大量符合要求的YES结果误判为NO。

给个最小复现用例:

输入:aebcde abcde
正确输出:YES(短串abcde是长串aebcde的子序列,按顺序取长串索引0的a、索引2的b、索引3的c、索引4的d、索引5的e即可)
你的代码输出:NO

逐行跑下这个用例就能看到错误触发过程:

  1. 初始短串匹配指针i=0,结果串res为空
  2. 长串第一个字符是a,确实在短串从0开始的子串里,i变成1,res拼上a,这一步逻辑正确
  3. 长串第二个字符是e,代码判断e在短串从1开始的子串bcde里存在,直接把i加为2,res拼上e——这步就是核心错误:此时短串等待匹配的第一个字符是b,e虽然在短串后续部分存在,但位置比b靠后,提前匹配e相当于直接跳过了待匹配的b,等后面遍历到长串里的b时,短串从i=2开始的子串是cde,根本找不到b,自然匹配失败
  4. 后续遍历到b时直接跳过,再依次匹配c、d、e,最后res是aecde,和短串abcde不相等,就误判返回了NO。

另外代码还有个兼容性小问题:用input().split()读取输入,如果题目允许字符串本身包含空格,会直接读入错误,但从给出的测试用例看,评测机是用单个空格分隔两个无空格字符串,这个不是导致用例不通过的核心原因。

修复方案

子序列匹配用标准双指针逻辑即可,不需要拼接结果串,也不需要做in子串判断,时间复杂度O(n),逻辑稳定不会出错:

  • 给短串设一个匹配指针,初始指向0位置
  • 遍历长串的每个字符,如果当前字符等于短串指针指向的字符,就把短串指针后移一位
  • 长串遍历完后,判断短串指针是否走到短串末尾即可

修复后的参考代码:

def is_subsequence(long_str, short_str):
    short_idx = 0
    len_short = len(short_str)
    for c in long_str:
        if short_idx < len_short and c == short_str[short_idx]:
            short_idx += 1
    return short_idx == len_short

m, w = input().split()
# 保证长串在前,短串在后
if len(m) < len(w):
    m, w = w, m
print("YES" if is_subsequence(m, w) else "NO")

这个写法可以直接覆盖原代码中m==w的边界判断,不需要单独写分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:39:19