实现字符串不被识别为其他字符串中间子串的逻辑及代码问题
整词匹配逻辑修正方案
我们需要实现整词完全匹配效果,避免子串误匹配:比如目标词Birthday!不会匹配句子Happy Birthday Scott中的Birthday,也不会出现cat匹配category这类子串误判的情况。
原有代码问题梳理
- 变量笔误:函数第一个参数命名为
string,后续代码直接使用未定义的str变量,编译无法通过 - 转小写逻辑错误:给句子转小写的循环中错误读取
str的字符,而非sentence的字符,导致句子预处理完全错误 - 死代码:调用
strstr找到子串后直接返回true,后续的匹配判断逻辑永远不会执行 - 无整词边界校验:仅用
strstr只能判断子串存在,无法校验是否为独立完整的词,是子串误匹配的核心原因 - 缓冲区溢出风险:固定长度100字节的临时数组没有做长度校验,输入过长的字符串会触发内存越界
- 传入参数
wordNum未使用:以下方案默认实现全局整词匹配,如果你需要匹配句子中第N个词,可基于边界拆分逻辑调整即可。
修正后实现代码
#include <cstring> #include <cctype> // 辅助函数:判断字符是否为单词分隔符(空格、标点、控制符都算分隔符,可按需调整规则) static bool isWordDelimiter(char c) { return isspace(c) || ispunct(c) || c == '\0'; } int Words::matchWords(const char* target, const char* sentence, int wordNum) { int wordCount = words(sentence); if (wordNum > wordCount) { return false; } int targetLen = strlen(target); int sentLen = strlen(sentence); // 目标词比句子还长直接返回不匹配 if (targetLen > sentLen) { return false; } // 动态分配临时缓冲区,避免固定长度溢出 char* targetLower = new char[targetLen + 1]; char* sentLower = new char[sentLen + 1]; // 统一转小写,实现大小写不敏感匹配 for (int i = 0; i < targetLen; i++) { targetLower[i] = tolower(target[i]); } targetLower[targetLen] = '\0'; for (int i = 0; i < sentLen; i++) { sentLower[i] = tolower(sentence[i]); } sentLower[sentLen] = '\0'; bool matched = false; char* curPos = sentLower; // 循环查找所有子串匹配位置,逐一校验边界 while ((curPos = strstr(curPos, targetLower)) != NULL) { int matchOffset = curPos - sentLower; // 校验前边界:要么是字符串开头,要么前一个字符是分隔符 bool frontValid = (matchOffset == 0) || isWordDelimiter(sentLower[matchOffset - 1]); // 校验后边界:要么是字符串结尾,要么后一个字符是分隔符 bool backValid = (matchOffset + targetLen == sentLen) || isWordDelimiter(sentLower[matchOffset + targetLen]); if (frontValid && backValid) { matched = true; break; } // 跳过当前匹配位置,继续找下一个 curPos += targetLen; } // 释放动态内存 delete[] targetLower; delete[] sentLower; return matched; }
逻辑说明
- 新增分隔符判断规则,标点、空格、字符串首尾都算单词边界,如果你需要调整匹配规则(比如允许下划线作为单词一部分),直接修改
isWordDelimiter函数即可 - 遍历所有子串匹配结果,只有前后边界都符合要求才判定为匹配成功
- 改用动态内存分配存储转小写后的字符串,避免固定长度缓冲区溢出问题
- 修复了原有代码的变量笔误、转小写逻辑错误等问题
内容的提问来源于stack exchange,提问作者Yanru Shin
相关产品推荐
相关产品推荐

