三种变长编码方法的 C 实现
1.香农编码法
// shannon.c
// 编译指令:gcc shannon.c -lm
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int i, j, n;
printf("请输入信源符号个数:");
scanf("%d", &n);
printf("请输入各符号的概率:");
double x[n];
for (i = 0; i < n; i++) {
printf("x[%d]= ", i);
scanf("%lf", &x[i]);
}
// 选择排序(降序)
for (i = 0; i < n-1; i++) {
double v;
for (j = i+1, v = x[j]; v > x[j-1] && j >= 1; j--) {
x[j] = x[j-1];
}
x[j] = v;
}
// 计算码长:1-log2(p(xi))向上取整
int k[n];
for (i = 0; i < n; i++) {
k[i] = -log(x[i]) / log(2) + 1;
if (k[i] == (-log(x[i]) / log(2) + 1)) k[i] -= 1;
}
// 累加概率
double pa[n];
pa[0] = 0.0;
for (i = 1; i < n; i++) {
pa[i] = pa[i-1] + x[i-1];
}
// 将累加概率转换为二进制
char code[n][n];
for (i = 0; i < n; i++) {
double t = pa[i];
for (j = 0; j < k[i]; j++) {
double temp = 2*t;
if (temp > 1) {
code[i][j] = '1';
t = 2*t - 1;
} else {
code[i][j] = '0';
t = 2*t;
}
}
}
// 输出结果
printf("%16s %12s %16s %4s %4c%s\n", "信源", "概率p(x)", "累加概率", "码长", ' ', "码字code");
for (i = 0; i < n; i++) {
printf("%12d %12lf %12lf %4d %4c", i+1, x[i], pa[i], k[i], ' ');
for (j = 0; j < k[i]; j++) {
printf("%c", code[i][j]);
}
printf("\n");
}
return 0;
}2.费诺编码法
3.霍夫曼编码法
Last updated