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

C++中set显示size为1却无法打印元素的问题排查

问题分析与解决:std::set size显示1但遍历无输出的原因

核心问题:字符串下标越界访问

你的代码中存在未定义行为:外层循环i <= s.length()、内层循环j <= s.length(),当j等于s.length()时,s[j]访问的是超出std::string有效范围的内存位置。C++字符串的有效下标范围是0到s.length()-1,访问s.length()会读取未知内存值,大概率是'\0'(空字符)。

为什么size为1但遍历无输出

  • std::set<char>会将这个空字符存入集合,因此mems.size()返回1。
  • 空字符是不可打印字符,用cout输出时不会在控制台显示任何内容,所以遍历看起来没有元素输出,但集合内确实存在一个空字符元素。

为什么预期size为2未达成

原逻辑想要插入字符串的两个字符'a'和'u',但越界访问插入的空字符打乱了正常流程,同时内层循环中直接修改外层循环变量i的操作,也干扰了循环的正常迭代,导致集合无法按预期存储两个有效字符。

修复方案

  1. 修正循环条件,避免越界:将i <= s.length()改为i < s.length(),j <= s.length()改为j < s.length()。
  2. 优化逻辑:原嵌套循环的写法容易出错,改用滑动窗口实现最长无重复子串的逻辑更清晰可靠。

修正后的示例代码:

#include <algorithm>
#include <iostream>
#include <set>

using namespace std;

int main() {
    string s = "au";
    std::set<char> mems;
    int ans = 0;
    int left = 0;

    // 滑动窗口实现最长无重复子串
    for (int right = 0; right < s.length(); ++right) {
        // 若当前字符已存在,移除左边界字符直到无重复
        while (mems.count(s[right])) {
            mems.erase(s[left]);
            left++;
        }
        mems.insert(s[right]);
        ans = max(ans, right - left + 1);
    }

    cout << "最长无重复子串长度:" << ans << endl;
    cout << "集合元素:";
    for (auto item : mems) {
        cout << item << " ";
    }
    cout << endl;
    cout << "集合大小:" << mems.size() << endl;

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:25:02