递归字符串匹配算法隐藏用例失败:6测过5,3样例全过
排查递归字符串匹配算法的隐藏测试用例问题
Hey,我仔细看了你的代码和问题描述,能过大部分测试但卡在隐藏用例上,核心问题出在你的标记逻辑和分支覆盖的疏漏上,咱们拆解来看:
你的实现里的关键漏洞
1. 篡改原字符串的标记方式埋坑
你用把已验证字符改成'P'的方式来追踪进度,这会直接破坏原字符串的结构,后续递归的判断都是基于被修改后的内容,很容易触发错误的分支逻辑。比如当你把一个a改成P后,下一次递归会进入input[0] == 'P'的分支,但这个分支的判断逻辑并不完善,很容易误判。
2. 非法情况的分支覆盖不全
在input[0] == 'P'的分支里,你只处理了几种特定的非法场景(比如a后跟ba,bb后跟b),但还有大量非法情况没覆盖:
a后面跟单个b(不是bb):你的代码不会触发answer = false,会默认返回true,这明显违反规则2。bb后面跟bb:同样没有判断,会错误返回true,违反规则3。- 字符串开头不是
a:你的代码完全没处理这种情况,会走到最后的递归分支,导致错误结果。
3. 递归推进逻辑不符合规则
比如当你处理完a后面跟bb的情况时,应该直接跳到bb之后的位置继续判断,但你的代码只把input[1]设为P然后推进一个字符,这会导致后续重复处理已经验证过的bb部分,逻辑完全混乱。
4. 终止条件不够严谨
你的终止条件是input[0] == 'P' && input[1] == '\0',但如果是合法的短字符串(比如"a"),虽然能正确返回,但如果是更长的合法字符串,可能因为标记逻辑的混乱无法正确触发终止条件。
修正后的实现思路
其实完全不需要修改原字符串,我们可以通过传递当前索引位置来递归,这样逻辑更清晰,也不会破坏原字符串。核心逻辑紧扣规则:
- 字符串必须以
a开头,否则直接返回false。 - 遇到
a时,有三种合法后续:- 后面是空字符(字符串结束)→ 合法。
- 后面是
a→ 递归检查下一个a的位置。 - 后面是
bb→ 检查bb是否存在,然后递归检查bb之后的位置。
- 遇到
bb时(注意:bb只能出现在a之后,所以递归到这里的前提是前面已经合法),有两种合法后续:bb后面是空字符→ 合法。bb后面是a→ 递归检查这个a的位置。
- 其他所有情况都属于非法,返回
false。
修正后的代码
#include <iostream> #include <cstring> using namespace std; // 辅助递归函数,传入当前检查的索引 bool checkABHelper(char input[], int index) { // 已经遍历到字符串末尾,说明前面都合法 if (input[index] == '\0') { return true; } // 当前位置必须是a(因为合法的字符串只能以a开头,且后续合法节点只有a或bb,而bb只能在a之后) if (input[index] != 'a') { return false; } // 情况1:a后面是空字符,合法 if (input[index+1] == '\0') { return true; } // 情况2:a后面是a,递归检查下一个a if (input[index+1] == 'a') { return checkABHelper(input, index+1); } // 情况3:a后面是bb,先确认bb存在,再检查bb的后续 if (input[index+1] == 'b' && input[index+2] == 'b') { // bb后面是空字符,合法 if (input[index+3] == '\0') { return true; } // bb后面是a,递归检查这个a if (input[index+3] == 'a') { return checkABHelper(input, index+3); } // bb后面不是空或a,非法 return false; } // 其他情况:a后面不是空、a、bb,非法 return false; } bool checkAB(char input[]) { // 空字符串直接返回false,因为规则要求以a开头 if (strlen(input) == 0) { return false; } // 从索引0开始检查 return checkABHelper(input, 0); } int main() { char input[100]; cin >> input; cout << (checkAB(input) ? "true" : "false") << endl; return 0; }
测试验证
这个代码可以覆盖所有边界和非法情况:
- 合法测试用例:
"a"、"aa"、"abb"、"abba"、"abbaabb"(你的样例)都返回true。 - 非法测试用例:
"b"、"ab"、"abbab"、"abbb"、"abbaaab"都返回false。
你可以用这些用例验证,应该能通过所有测试,包括那个隐藏的。
内容的提问来源于stack exchange,提问作者user11555625
相关产品推荐
相关产品推荐

