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

C++连续字符统计代码输出多了额外‘1’,求问题原因

问题分析:字符串连续字符统计出现多余‘1’的原因

嘿,我来帮你揪出这个多余的‘1’到底是怎么冒出来的!

你预期输出是2a3b3c4d3l4z,但实际得到12a3b3c4d3l4z,核心问题出在字符串长度的计算和循环边界处理上,咱们一步步拆解:

问题1:错误使用sizeof获取字符串长度

你定义的char ipstr[] = "aabbbcccddddzzzzlll";是C风格字符串,它在内存里会自动在末尾添加一个空终止符\0来标记字符串结束。sizeof(ipstr)返回的是整个数组的字节数,包括这个\0,而不是实际的字符长度。

比如你的字符串实际字符数是19,加上\0后sizeof(ipstr)的值是20,这就导致循环多跑了一次。

问题2:循环越界并错误统计了\0

循环条件i < sizeof(ipstr)会让i从0跑到19(共20次):

  • 当i=19时,ipstr[i]就是末尾的\0,此时ipstr[i+1]属于越界访问内存(数组下标最大是19),程序行为是未定义的,但大概率ipstr[19] != ipstr[20],会进入else分支。
  • 此时num的值是0,所以ms['\0'] = 0 + 1 = 1,把空字符\0存入了map中。

而map<char, int>是按key的ASCII码升序排列的,\0的ASCII码是0,比所有字母都小,所以输出时会排在最前面。\0是不可见字符,所以输出时只显示它的计数1,后面跟着正常的2a3b...,就变成了你看到的12a3b3c4d3l4z。

额外提醒:map不适合统计连续字符

哦对了,顺便提一句:你的需求是统计连续字符的出现次数,但map会把所有相同字符的次数合并(比如如果字符串是aabbaa,map会把a的次数算成4,而不是2a2b2a)。如果你的需求确实是连续字符统计,应该直接输出结果而不是用map存储,这样更符合逻辑也更高效。

修复后的代码

基于map的修复版本(保持原存储逻辑)

把sizeof(ipstr)换成strlen(ipstr),同时调整循环条件避免越界(因为要比较ipstr[i]和ipstr[i+1],所以循环应该到i < strlen(ipstr) - 1):

#include <iostream>
#include <cstring> // 需要包含strlen的头文件
#include <map>
using namespace std;

int main() {
    char ipstr[] = "aabbbcccddddzzzzlll"; 
    cout << "size of string:" << strlen(ipstr) << endl; 
    int num = 0; 
    map<char, int> ms; 
    // 循环到倒数第二个字符,避免i+1越界
    for(int i = 0; i < strlen(ipstr) - 1; i++){ 
        if(ipstr[i] == ipstr[i+1]) {
            num++;
        } else {
            ms[ipstr[i]] = num + 1;
            num = 0;
        }
    }
    // 处理最后一组连续字符
    ms[ipstr[strlen(ipstr)-1]] = num + 1;
    
    for(auto it = ms.begin(); it != ms.end(); it++){
        cout << it->second << it->first;
    } 
    cout << endl;
    return 0;
}

直接输出连续字符的版本(更贴合需求)

如果不需要存储统计结果,直接遍历输出连续字符的计数会更高效:

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char ipstr[] = "aabbbcccddddzzzzlll"; 
    int len = strlen(ipstr);
    if(len == 0) return 0;
    
    int count = 1;
    for(int i = 1; i < len; i++){
        if(ipstr[i] == ipstr[i-1]){
            count++;
        } else {
            cout << count << ipstr[i-1];
            count = 1;
        }
    }
    // 输出最后一组连续字符
    cout << count << ipstr[len-1] << endl;
    return 0;
}

(注:原字符串里是4个z、3个l,map版本会按字母排序输出2a3b3c4d3l4z,直接输出版本会按原顺序输出2a3b3c4d4z3l,可根据需求选择)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:02:33