You need to enable JavaScript to run this app. 基于strtok统计字符串末位单词出现次数的代码异常排查
优惠活动
大模型
产品
解决方案
定价
更多

基于strtok统计字符串末位单词出现次数的代码异常排查

代码问题排查与修改方向

现有代码的核心逻辑偏差

你之前实现首个单词统计的逻辑是:第一次拿到切分结果就立刻确定目标词,后续所有切分结果都和这个目标词比对计数——这个逻辑对首个单词的场景是成立的,但硬套到最后一个单词的需求上,就会出现几个实打实的硬伤:

  • 错配了从旧代码遗留的判断逻辑:初始化nr=51试图靠递减到1来抓取最后一个单词,但nr的初始值和实际切出的单词数量没有任何关联。哪怕字符串只有3个单词,循环走完3次后nr只会从51降到48,永远触不到nr==1的判断分支,存目标词的strcpy(s1,p)根本不会被执行,s1全程是空值,后续的字符串比对全是无效操作。
  • 统计时机完全错位:就算你能侥幸触发最后一个单词的存储分支,这个单词也是在循环的最后一次迭代才被存入s1,在这之前的所有切分结果,因为目标词还没确定,strcmp的比对没有任何意义,自然统计不到正确的出现次数。
  • 初始计数逻辑不匹配:你把k初始化为1,是沿用了首个单词统计的设定——第一个单词本身就是目标词,所以从1开始计数。但在最后一个单词的统计场景下,你没有办法在一开始就确定目标词,这个初始值的设定从根上就不成立。
  • 边界场景直接失效:如果输入字符串只有1个单词,按现有逻辑根本触发不了目标词存储的分支,统计结果必然和实际情况不符。

正确的修改方向

这个需求和首个单词统计的实现逻辑有本质区别,不能直接小改循环里的判断条件,得拆成两步走:

  1. 先把整个输入字符串按分隔符全部切分遍历,每拿到一个非空的切分结果,就把它覆盖存入临时存储区s1——等所有单词切完,最后一次覆盖存入的内容自然就是字符串里的最后一个单词,也就是我们要统计的目标词。
  2. 等目标词完全确定之后,再重新遍历所有切出来的单词,逐次比对和目标词是否一致,累计相等的次数就是最终要输出的结果。

调整后的核心代码参考(完全沿用你原来定义的变量):

char s[51], *p, sep[]=" ,.", s1[21];
int k = 0;
cin.get(s, 51);
// 第一次遍历:确定最后一个单词作为统计目标
p = strtok(s, sep);
while(p != nullptr) {
    strcpy(s1, p); // 每次覆盖,循环结束后s1存的就是最后一个单词
    p = strtok(nullptr, sep);
}
// 第二次遍历:统计目标词的出现次数
p = strtok(s, sep); // strtok会直接修改原字符串结构,需要从头重新切分
while(p != nullptr) {
    if(strcmp(s1, p) == 0) k++;
    p = strtok(nullptr, sep);
}
cout << k;

注意:strtok函数在切分过程中会把原字符串里的分隔符替换成字符串结束标记,第一次切分完成后原字符串的结构已经被改变,所以第二次计数的时候必须重新把字符串头指针传给strtok,才能正常遍历所有单词。


内容的提问来源于stack exchange,提问作者Bredor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 13:06:03