如何修正该字符串子串匹配的遍历方法?附问题代码
子串匹配函数
esSubString的问题分析与修复 核心问题拆解
原代码里的while(j<lngSubStr && coincidencia)循环直接导致匹配逻辑失效,另外还有几个逻辑bug:
- 内层循环强制重置j:每次进入这个循环都把j设为0,相当于永远只对比子串的第一个字符,根本没法完成多字符子串的完整匹配。
- 匹配失败后i没回溯:一旦某次匹配失败,i已经跑到当前起始位置后面去了,没回到起始位置的下一个位置重新尝试,直接错过后续可能的匹配。
- 多余的字母跳过逻辑:那个
saltando循环会跳过所有字母,完全和子串匹配的需求冲突,除非有特殊需求未说明,否则这个逻辑必须删掉。 - 变量初始化时机错了:j应该在每次尝试新的匹配起始点时重置为0,而不是扔在内层循环里。
修复后的完整代码
#include "substring.h" #include <string.h> #include <iostream> using namespace std; bool esSubString(char str[], char subStr[], int& posicio) { int lngSubStr = strlen(subStr); int lngStr = strlen(str); // 处理子串为空的边界情况 if (lngSubStr == 0) { posicio = 0; return true; } bool trobat = false; int i = 0; // 优化循环边界:剩余字符长度不够子串长度时直接终止 while (i <= lngStr - lngSubStr && !trobat) { posicio = i; int j = 0; bool coincidencia = true; // 逐个字符匹配子串 while (j < lngSubStr && coincidencia) { if (subStr[j] != str[i + j]) { coincidencia = false; } else { j++; } } if (coincidencia) { trobat = true; } else { // 匹配失败,移到下一个起始位置继续尝试 i++; } } // 没找到的话把posicio设为-1,明确标识未找到 if (!trobat) { posicio = -1; } return trobat; }
修复要点说明
- 修正内层匹配逻辑:把j的初始化移到外层循环每次尝试新起始点的时候,然后逐个对比
subStr[j]和str[i+j],确保能完整遍历子串完成匹配。 - 优化循环边界:外层循环改成
i <= lngStr - lngSubStr,当主字符串剩余长度比子串短的时候,直接停止循环,避免做无用功。 - 添加边界处理:加入了子串为空的情况判断,符合常规字符串匹配的逻辑(空串默认是任何字符串的子串)。
- 删除错误的跳过逻辑:把那个破坏匹配流程的
saltando循环直接删掉,回归正常的子串匹配逻辑。 - 匹配失败的正确处理:每次匹配失败后,i递增1,移到下一个起始位置继续尝试,不会错过可能的匹配。
- 未找到的状态标识:如果最终没匹配到子串,把
posicio设为-1,方便调用方判断结果。
内容的提问来源于stack exchange,提问作者Marco M D
相关产品推荐
相关产品推荐

