rle仅适用于连续重复字符多的字符串,如“aaabbbcccd”,且需预检重复段平均长度≥2;实现时应遍历统计连续字符数,用reserve避免realloc,to_string转数字,append拼接。

Run-Length编码的适用场景和前提条件
Run-Length Encoding(RLE)只对连续重复字符多的字符串有效,比如 "aaabbbcccd" 压缩后是 "a3b3c3d1";但对随机字符串如 "abcabc" 反而会变长。实际使用前必须判断:重复段平均长度是否 ≥ 2,否则不建议启用。
常见误用是直接套用 RLE 处理所有字符串,结果体积增大、解码失败——因为没做“是否值得压缩”的预检。
如何用 std::string 实现基础 RLE 编码函数
核心逻辑是遍历字符串,统计当前字符连续出现次数,遇到不同字符或结尾时写入结果。注意边界处理和数字转字符串的开销:
- 用
size_t i = 0遍历,内层用while找连续段,避免嵌套 for 循环出错 - 计数用
int count即可(单段不会超INT_MAX),但转换成字符串时用std::to_string(count),别手写除法 - 不要在循环里反复调用
result += ...,改用result.append()或预留容量:result.reserve(input.size())
示例片段:
立即学习“C++免费学习笔记(深入)”;
std::string rle_encode(const std::string& s) {
if (s.empty()) return s;
std::string result;
result.reserve(s.size()); // 预分配防频繁 realloc
char curr = s[0];
int count = 1;
for (size_t i = 1; i <= s.size(); ++i) {
if (i == s.size() || s[i] != curr) {
result += curr;
result += std::to_string(count);
if (i < s.size()) {
curr = s[i];
count = 1;
}
} else {
++count;
}
}
return result;
}
解码时容易忽略的字符与数字解析陷阱
解码函数常假设输入格式严格为“字母+数字”交替,但实际可能遇到:"a12b3"(两位数计数)、"x1y100",甚至非法输入如 "a1b"(末尾缺数字)或 "123"(开头无字母)。必须做两件事:
- 用
std::isdigit()判断数字起始,再用std::stoi()或手动累加解析多位数,不能只取下一位 - 检查解码过程中是否越界:比如解析到字符串末尾却还没读完数字,应视为无效输入并返回空串或抛异常
- 注意字符范围:RLE 通常只处理 ASCII 字符,若输入含
'0'~'9'本身,该算法无法无损压缩——这是 RLE 的固有局限,不是 bug
性能关键点:避免 string 拼接和重复构造
在高频调用或长字符串场景下,+= 操作可能触发多次内存分配。实测表明,对 10MB 全 'a' 字符串,未 reserve 的编码耗时比 reserve 后高 3–5 倍。
另一个坑是返回值方式:不要写 return result + "..."; 这类表达式,C++11 后虽有 RVO,但某些编译器优化不稳;统一用命名变量 + 移动返回:return std::move(result);(不过对小字符串意义不大,优先保证可读性)。
如果需极致性能,可改用 std::vector<char></char> 手动管理缓冲区,但练习阶段用 std::string 更安全——毕竟 RLE 本就不是为大数据设计的。










