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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:45:09