RLE编码后输出符号数统计方法及现有C代码问题排查
问题原因分析
- 原有递减计数逻辑错误
你仅在重复次数大于2时对
m做1次递减,没有考虑不同重复长度对应的输出字符数差异:比如重复4次的字符输出为字符+数字共2个字符,比原长度少2,仅减1自然计算结果错误。
- printf返回值用法错误
printf的返回值是单次调用输出的字符数,你测试的
printf("%C%d", str[i], count[i])在重复次数为个位数时确实返回2,但你没有累加每次调用的返回值,而是直接将单次返回值作为总数输出,自然无法得到正确结果。如果重复次数大于等于10,该调用的返回值会变成3,你的写法也无法适配。
正确实现方案
推荐使用累加printf返回值的方案,不需要手动计算长度,适配所有场景:
- 初始化编码后字符计数变量
ks = 0 - 每次调用printf输出编码结果时,将返回值累加到
ks - 输入校验逻辑提前到编码前执行,避免无效输出
修正后的完整代码如下:
#include <stdio.h> #include <string.h> #include <ctype.h> int main() { int i = 0, b, c, s = 0, ks = 0, count[300] = {0}; char str[300]; float kompr; scanf("%s", str); c = strlen(str); s = c; // 输入符号数直接等于字符串长度,无需循环累加 // 提前做输入校验 for (i = 0; i < c; i++) { if (islower(str[i])) { fprintf(stderr, "\nError: Invalid input!\n"); return 100; } } // 编码同时统计输出字符数 for (i = 0; i < c;) { b = 0; count[i] = 1; do { b++; if (str[i + b] == str[i]) { count[i]++; } } while (str[i + b] == str[i]); if (count[i] <= 2) { ks += printf("%c", str[i]); i++; } else { ks += printf("%c%d", str[i], count[i]); i += count[i]; } } printf("\n"); // 按你预期输出0.25的要求,压缩比公式调整为(原长-新长)/原长,若需要标准新长/原长可修改为 (float)ks / s kompr = (float)(s - ks) / s; fprintf(stderr, "\n"); fprintf(stderr, "Input Symbols: %d\n", s); fprintf(stderr, "Coded Symbols: %d\n", ks); fprintf(stderr, "Compresion Ratio: %.2f\n", kompr); return 0; }
测试验证
输入AAAABCCD时:
- 标准输出:
A4BCCD - stderr输出:
Input Symbols: 8 Coded Symbols: 6 Compresion Ratio: 0.25
完全符合预期效果。
内容的提问来源于stack exchange,提问作者SajLenc
相关产品推荐
相关产品推荐

