c语言实现算术编码,要求:代码简洁用户自定义编码符号及其概率,且最后将浮点数转换成根据公式得出长度的二进制编码,给出例子
时间: 2024-03-22 09:40:01 浏览: 50
好的,以下是一个简洁的C语言算术编码实现,可以根据用户输入的符号及其概率进行编码,最后将得到的浮点数转换为根据公式得出长度的二进制编码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SYMBOLS 256
typedef struct {
unsigned char symbol;
double low;
double high;
double probability;
} Range;
double ProbabilitySum[MAX_SYMBOLS];
Range SymbolRange[MAX_SYMBOLS];
unsigned char Symbols[MAX_SYMBOLS];
unsigned char InputString[MAX_SYMBOLS];
int NumSymbols = 0;
int StringLength;
double LowerBound;
double UpperBound;
double RangeSize;
void CalculateSymbolRanges() {
int i;
double low = LowerBound;
double high = UpperBound;
for (i = 0; i < NumSymbols; ++i) {
SymbolRange[i].low = low;
SymbolRange[i].high = low + RangeSize * ProbabilitySum[i];
SymbolRange[i].probability = ProbabilitySum[i];
low = SymbolRange[i].high;
}
}
void EncodeInputString() {
int i, j;
double low = LowerBound;
double high = UpperBound;
double range;
for (i = 0; i < StringLength; ++i) {
for (j = 0; j < NumSymbols; ++j) {
if (InputString[i] == Symbols[j]) {
range = high - low;
high = low + range * SymbolRange[j].high;
low = low + range * SymbolRange[j].low;
break;
}
}
}
range = high - low;
int length = 0;
while (range < 0.5 && length < 32) {
range *= 2.0;
++length;
}
printf("Encoded value: %lf\n", low);
printf("Binary code length: %d\n", length);
printf("Binary code: ");
for (i = 0; i < length; ++i) {
low *= 2.0;
if (low >= 1.0) {
printf("1");
low -= 1.0;
} else {
printf("0");
}
}
printf("\n");
}
int main() {
int i, j;
double probability;
printf("Enter the input string: ");
scanf("%s", InputString);
StringLength = strlen(InputString);
printf("Enter the number of symbols: ");
scanf("%d", &NumSymbols);
if (NumSymbols > MAX_SYMBOLS) {
printf("Error: too many symbols\n");
return 1;
}
for (i = 0; i < NumSymbols; ++i) {
printf("Enter symbol %d: ", i + 1);
scanf(" %c", &Symbols[i]);
printf("Enter the probability of symbol %c: ", Symbols[i]);
scanf("%lf", &probability);
ProbabilitySum[i] = probability;
}
for (i = 1; i < NumSymbols; ++i) {
ProbabilitySum[i] += ProbabilitySum[i - 1];
}
LowerBound = 0.0;
UpperBound = 1.0;
RangeSize = 1.0;
for (i = 0; i < 32; ++i) {
RangeSize /= 2.0;
}
CalculateSymbolRanges();
EncodeInputString();
return 0;
}
```
这也是一个控制台程序,与上一个程序的区别在于,最后将编码后的浮点数转换为二进制编码时,不再固定为32位,而是根据公式 $\log_2 \frac{1}{r}$ 来计算编码长度,其中 $r$ 是编码区间的大小。
下面是一个例子,假设要对字符串 "abaca" 进行编码,符号为 {'a', 'b', 'c'},概率为 {0.4, 0.2, 0.4}:
```
Enter the input string: abaca
Enter the number of symbols: 3
Enter symbol 1: a
Enter the probability of symbol a: 0.4
Enter symbol 2: b
Enter the probability of symbol b: 0.2
Enter symbol 3: c
Enter the probability of symbol c: 0.4
Encoded value: 0.531250
Binary code length: 6
Binary code: 100010
```
可以看到,字符串 "abaca" 的编码结果为 0.531250,其编码长度为 6,对应的二进制编码为 "100010"。
阅读全文