C++从句子指定单词位置匹配字符串的实现及优化咨询
现有代码存在的问题
- 边界校验缺失:未判断
wordNum <= 0的情况,不符合规则3的要求 - 核心匹配逻辑完全不符合需求:当前用
strstr做全局模糊匹配,既没有限定从第wordNum个单词的起始位置开始匹配,也不支持大小写不敏感,更没有判断str结尾是否落在单词中间 - 严重安全风险:固定长度100字节的临时缓冲区,只要输入的字符串长度超过99就会触发栈溢出
- 鲁棒性不足:调用
isspace时未做无符号字符转换,遇到字符值为负的场景会触发未定义行为
优化实现方案
以下实现完全匹配你的需求,同时兼容原有单词计数规则(空白符、./,/!为单词分隔符):
#include <cctype> #include <cstring> // 优化后的单词计数函数,增强鲁棒性 int Directive::words(const char* sentence) { int wordCount = 0; int letterCount = 0; while (*sentence) { unsigned char c = static_cast<unsigned char>(*sentence); if (isspace(c) || c == '.' || c == ',' || c == '!') { if (letterCount) { wordCount++; } letterCount = 0; } else { letterCount++; } sentence++; } if (letterCount) { wordCount++; } return wordCount; } // 优化后的匹配函数 bool Directive::matchDirective(const char* str, const char* sentence, int wordNum) { // 规则3校验:非法序号直接返回不匹配 int totalWords = words(sentence); if (wordNum <= 0 || wordNum > totalWords) { return false; } int strLen = static_cast<int>(strlen(str)); if (strLen == 0) { return false; // 空匹配串可根据业务需求调整返回值 } // 第一步:定位第wordNum个单词的起始位置 const char* wordStart = sentence; int currentWord = 0; int letterCount = 0; const char* p = sentence; while (*p) { unsigned char c = static_cast<unsigned char>(*p); if (isspace(c) || c == '.' || c == ',' || c == '!') { if (letterCount) { currentWord++; if (currentWord == wordNum - 1) { wordStart = p + 1; // 跳过连续分隔符(多个空格、连续标点的场景) while (*wordStart) { unsigned char wc = static_cast<unsigned char>(*wordStart); if (isspace(wc) || wc == '.' || wc == ',' || wc == '!') { wordStart++; } else { break; } } } } letterCount = 0; } else { letterCount++; } p++; } // 第二步:大小写不敏感前缀匹配 for (int i = 0; i < strLen; i++) { if (wordStart[i] == '\0') { return false; } unsigned char c1 = static_cast<unsigned char>(tolower(str[i])); unsigned char c2 = static_cast<unsigned char>(tolower(wordStart[i])); if (c1 != c2) { return false; } } // 第三步:规则2校验:str结尾不能落在单词中间 unsigned char endChar = static_cast<unsigned char>(wordStart[strLen]); if (endChar == '\0' || isspace(endChar) || endChar == '.' || endChar == ',' || endChar == '!') { return true; } return false; }
开头空白字符的适配说明
本次实现和原有单词计数逻辑保持了一致的分隔符判断规则,开头的空白字符触发分隔判断时,因为有效字符计数为0,不会被统计为有效单词,定位目标单词的逻辑也会自动跳过开头的所有空白/分隔符,不需要额外做特殊适配。
内容的提问来源于stack exchange,提问作者Yanru Shin
相关产品推荐
相关产品推荐

