基于朴素固定长度编码编写字符串编码的c语言代码,并输出数据为哈夫曼编码后的平均长度,保留两位小数(四舍五入)。
时间: 2023-12-03 17:46:36 浏览: 40
以下是基于朴素固定长度编码编写字符串编码的C语言代码,并输出数据为哈夫曼编码后的平均长度,保留两位小数(四舍五入):
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1000
#define CODE_LEN 5
typedef struct node {
char c;
int freq;
struct node *left, *right;
} Node;
typedef struct code {
char c;
char bits[CODE_LEN + 1];
} Code;
void count_freq(char *str, int *freq) {
for (int i = 0; i < strlen(str); i++) {
freq[(int)str[i]]++;
}
}
Node *new_node(char c, int freq) {
Node *node = (Node *)malloc(sizeof(Node));
node->c = c;
node->freq = freq;
node->left = NULL;
node->right = NULL;
return node;
}
Node *build_huffman_tree(int *freq) {
Node *min1, *min2, *node;
int min1_freq, min2_freq;
int i, j, min1_index, min2_index;
Node *nodes[MAX_LEN];
for (i = 0, j = 0; i < 256; i++) {
if (freq[i] > 0) {
nodes[j++] = new_node(i, freq[i]);
}
}
while (j > 1) {
min1_index = min2_index = -1;
min1_freq = min2_freq = MAX_LEN;
for (i = 0; i < j; i++) {
if (nodes[i]->freq < min1_freq) {
min2_index = min1_index;
min2_freq = min1_freq;
min1_index = i;
min1_freq = nodes[i]->freq;
} else if (nodes[i]->freq < min2_freq) {
min2_index = i;
min2_freq = nodes[i]->freq;
}
}
min1 = nodes[min1_index];
min2 = nodes[min2_index];
node = new_node(0, min1_freq + min2_freq);
node->left = min1;
node->right = min2;
nodes[min1_index] = node;
nodes[min2_index] = nodes[--j];
}
return nodes[0];
}
void encode(Node *root, Code *codes, char *bits, int depth) {
if (root->left == NULL && root->right == NULL) {
for (int i = 0; i < 256; i++) {
if (root->c == i) {
codes[i].c = root->c;
strcpy(codes[i].bits, bits);
break;
}
}
return;
}
bits[depth] = '0';
encode(root->left, codes, bits, depth + 1);
bits[depth] = '1';
encode(root->right, codes, bits, depth + 1);
}
void print_codes(Code *codes) {
for (int i = 0; i < 256; i++) {
if (strlen(codes[i].bits) > 0) {
printf("%c: %s\n", codes[i].c, codes[i].bits);
}
}
}
float calc_avg_length(Code *codes, int *freq) {
float sum = 0;
for (int i = 0; i < 256; i++) {
if (strlen(codes[i].bits) > 0) {
sum += freq[i] * strlen(codes[i].bits);
}
}
return sum / strlen(input);
}
int main() {
char input[MAX_LEN];
int freq[256] = {0};
Code codes[256] = {0};
Node *root;
char bits[CODE_LEN + 1] = {0};
float avg_len;
printf("Enter a string: ");
fgets(input, MAX_LEN, stdin);
input[strcspn(input, "\n")] = 0;
count_freq(input, freq);
root = build_huffman_tree(freq);
encode(root, codes, bits, 0);
print_codes(codes);
avg_len = calc_avg_length(codes, freq);
printf("Average length after Huffman coding: %.2f\n", avg_len);
return 0;
}
```
注意,这里的固定长度编码使用了5位二进制,即每个字符都被编码成5位二进制数。在实际应用中,固定长度编码可能会浪费空间,因为某些字符出现的频率较高,但是它们的编码长度仍然是5位,这样就浪费了一些空间。
哈夫曼编码则是一种变长编码,根据字符出现的频率不同,使用不同长度的二进制数来表示字符。这样可以减少编码长度,提高编码效率。
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)