c++实现rle压缩应采用双指针遍历,核心是处理空串、单字符、末尾段及越界边界:空串直接返回;单字符输出“1c”;循环外补最后一段;计数用j-i;不加数字分隔符以保证可逆性。
a3)">
直接上结论:C++ 里做 AAA->A3 这种基础游程编码(RLE),用双指针遍历 + 计数最稳妥,std::string 拼接即可,不需要额外库或正则。
怎么写一个安全的压缩函数(避免越界和空串崩溃)
核心是用两个下标 i 和 j:固定 i 指向当前字符起点,j 向后滑动直到字符变化。关键要处理边界——j 必须小于 s.size(),且循环结束后还得手动追加最后一段。
- 空字符串或单字符直接返回原串,不进主循环
- 循环内用
s[j] == s[i]判断,不是s[j] == s[j-1],避免j==0时访问s[-1] - 计数用
j - i,不是j - i + 1,因为j已停在第一个不同字符位置
std::string compress(const std::string& s) {
if (s.empty()) return s;
std::string res;
size_t i = 0;
while (i 1) res += std::to_string(j - i);
i = j;
}
return res;
}
为什么不用 std::stringstream 或 std::format(C++20)
std::to_string 足够轻量,无异常风险;std::stringstream 开销大,且容易因忘记清空状态导致拼接错乱;std::format 虽简洁但 C++20 支持不统一,MSVC 2022 22.34+ 才稳定,GCC 13 默认不启用。
- 如果必须用
std::stringstream,每次循环前要调用ss.str("")清空缓冲区 -
std::format("{0}{1}", s[i], j-i)在 Clang 15+ 且开启-std=c++20 -fformat-extensions下才可用 - 数字转字符串性能:
std::to_string≈ 手写除10循环,远快于流式操作
压缩结果要不要加分隔符(比如 A3B2 vs A3,B2)
原始需求 AAA->A3 明确不要分隔符。加逗号或下划线会破坏可逆性——解压时无法确定数字位数(A12 是 A 重复 12 次,还是 A1 和 2?)。除非协议约定数字固定两位,否则一律不加。
- 若输入含数字(如
"A11"),此压缩逻辑会输出"A11"→"A11"(误认为 A 重复 11 次),属于设计局限,需提前约定输入不含数字 - 大小写敏感:
"AaA"压缩为"A1a1A1",不会合并,符合 ASCII 比较规则 - 连续相同字符超过 9 次(如 15 个
A)输出"A15",没有长度限制
真正麻烦的是解压时的数字解析——得从左到右扫描,遇到字母记为 ch,之后连续读数字字符再转整型,这个过程比压缩容易出错。压缩本身逻辑简单,但别忘了测试 "A"、"AA"、"AB"、"" 这几类边界。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











