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

C++使用stringstream获取字符串所有连续N长度子串及优化

问题根因
  • 滑动步长错误:std::stringstream::read执行后会将流的读取指针向后移动size位,导致每次窗口偏移size长度而非1位,自然缺失偏移为奇数的窗口。
  • 迭代次数计算错误:长度为L的字符串,长度为N的有效滑动窗口总数为L >= N ? L - N + 1 : 0,原代码少算1次有效窗口,且未处理字符串长度小于窗口的边界场景。
  • 读取失败无处理:当流读取到末尾时,read操作不会覆盖原有result内容,导致末尾重复输出错误的窗口值。
  • 性能损耗:std::stringstream会产生额外的字符串拷贝和流操作开销,完全不适合处理5M以上的超长字符串。
高效修复实现

以下实现全程无额外内存分配,性能拉满,完全适配大字符串场景:

#include <iostream>
#include <string>

template<std::size_t WindowSize>
void update(const std::string& s) {
    // 长度不足直接返回,忽略尾部不足窗口
    if (s.size() < WindowSize) {
        return;
    }
    // 关闭stdio同步可进一步提升输出性能,建议在main函数入口执行一次即可
    // std::ios::sync_with_stdio(false);
    // std::cin.tie(nullptr);
    const std::size_t total = s.size() - WindowSize + 1;
    for (std::size_t i = 0; i < total; ++i) {
        // 直接输出指定长度字符,无需构造临时字符串
        std::cout.write(s.data() + i, WindowSize);
        std::cout.put('\n');
    }
}

如果使用C++17及以上标准,也可以用std::string_view实现零拷贝窗口构造,逻辑完全一致。

优化说明

  • 用std::ostream::write直接输出原字符串的指定区间,无临时字符串构造开销
  • 用'\n'替代std::endl,避免每次输出强制刷新缓冲区,输出性能提升数倍
  • 提前做边界判断,无非法内存访问风险
  • 开启std::ios::sync_with_stdio(false)后,输出性能接近C标准库printf水平,适合大数量窗口输出场景
运行验证

用你给出的测试用例执行后,输出结果为:

ab
bc
cd
de
ef
fg

你给出的预期输出漏了de项,属于笔误,上述输出是滑动窗口切分的标准结果。

内容的提问来源于stack exchange,提问作者d-man

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:45:04