c语言对任意字符串中字母、标点符号的使用频率进行统计,然后对出现的字母和标点符号进行哈夫曼编码
时间: 2023-12-10 11:41:54 浏览: 158
使用c语言实现哈夫曼编码
首先,我们需要对字符串中的字母和标点符号进行统计。可以使用一个数组来存储每个字母和标点符号出现的次数,数组下标表示字符的 ASCII 码值。
```c
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000
int freq[256]; // 用于存储各个字符出现的频率
int main()
{
char str[MAX_LEN];
int len, i;
printf("请输入字符串:");
fgets(str, MAX_LEN, stdin);
len = strlen(str);
// 统计各个字符出现的频率
for (i = 0; i < len; i++) {
freq[(unsigned char)str[i]]++;
}
// 打印各个字符的出现频率
for (i = 0; i < 256; i++) {
if (freq[i] > 0) {
printf("%c:%d\n", i, freq[i]);
}
}
return 0;
}
```
接下来,我们需要实现哈夫曼编码。哈夫曼编码是一种可变长度编码,将频率较高的字符用较短的编码表示,而频率较低的字符用较长的编码表示,从而达到压缩数据的目的。
首先,我们需要定义一个结构体来表示哈夫曼树的节点。
```c
struct huffman_node {
char ch; // 字符
int freq; // 频率
struct huffman_node *left; // 左子树
struct huffman_node *right; // 右子树
};
```
然后,我们需要实现一个比较函数,用于排序。
```c
int cmp(const void *a, const void *b)
{
struct huffman_node *na = (struct huffman_node *)a;
struct huffman_node *nb = (struct huffman_node *)b;
return nb->freq - na->freq;
}
```
接下来,我们需要实现一个函数,用于构建哈夫曼树。
```c
struct huffman_node *build_huffman_tree(int freq[])
{
struct huffman_node *nodes[256];
int i, j, n;
// 构建叶子节点
for (i = 0, n = 0; i < 256; i++) {
if (freq[i] > 0) {
nodes[n] = malloc(sizeof(struct huffman_node));
nodes[n]->ch = i;
nodes[n]->freq = freq[i];
nodes[n]->left = NULL;
nodes[n]->right = NULL;
n++;
}
}
// 构建哈夫曼树
while (n > 1) {
// 找到频率最小的两个节点
qsort(nodes, n, sizeof(struct huffman_node *), cmp);
struct huffman_node *left = nodes[n-1];
struct huffman_node *right = nodes[n-2];
// 创建新节点
struct huffman_node *parent = malloc(sizeof(struct huffman_node));
parent->ch = 0;
parent->freq = left->freq + right->freq;
parent->left = left;
parent->right = right;
// 将新节点加入节点数组
nodes[n-2] = parent;
n--;
}
return nodes[0];
}
```
最后,我们需要实现一个函数,用于对字符串进行哈夫曼编码。
```c
void huffman_encode(char str[], struct huffman_node *root)
{
int len = strlen(str);
int i;
// 逐个字符进行编码
for (i = 0; i < len; i++) {
struct huffman_node *node = root;
// 循环直到找到叶子节点
while (node->left != NULL || node->right != NULL) {
if (str[i] == node->left->ch) {
putchar('0');
node = node->left;
} else {
putchar('1');
node = node->right;
}
}
}
}
```
完整代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LEN 1000
struct huffman_node {
char ch; // 字符
int freq; // 频率
struct huffman_node *left; // 左子树
struct huffman_node *right; // 右子树
};
int freq[256]; // 用于存储各个字符出现的频率
int cmp(const void *a, const void *b)
{
struct huffman_node *na = (struct huffman_node *)a;
struct huffman_node *nb = (struct huffman_node *)b;
return nb->freq - na->freq;
}
struct huffman_node *build_huffman_tree(int freq[])
{
struct huffman_node *nodes[256];
int i, j, n;
// 构建叶子节点
for (i = 0, n = 0; i < 256; i++) {
if (freq[i] > 0) {
nodes[n] = malloc(sizeof(struct huffman_node));
nodes[n]->ch = i;
nodes[n]->freq = freq[i];
nodes[n]->left = NULL;
nodes[n]->right = NULL;
n++;
}
}
// 构建哈夫曼树
while (n > 1) {
// 找到频率最小的两个节点
qsort(nodes, n, sizeof(struct huffman_node *), cmp);
struct huffman_node *left = nodes[n-1];
struct huffman_node *right = nodes[n-2];
// 创建新节点
struct huffman_node *parent = malloc(sizeof(struct huffman_node));
parent->ch = 0;
parent->freq = left->freq + right->freq;
parent->left = left;
parent->right = right;
// 将新节点加入节点数组
nodes[n-2] = parent;
n--;
}
return nodes[0];
}
void huffman_encode(char str[], struct huffman_node *root)
{
int len = strlen(str);
int i;
// 逐个字符进行编码
for (i = 0; i < len; i++) {
struct huffman_node *node = root;
// 循环直到找到叶子节点
while (node->left != NULL || node->right != NULL) {
if (str[i] == node->left->ch) {
putchar('0');
node = node->left;
} else {
putchar('1');
node = node->right;
}
}
}
}
int main()
{
char str[MAX_LEN];
int len, i;
printf("请输入字符串:");
fgets(str, MAX_LEN, stdin);
len = strlen(str);
// 统计各个字符出现的频率
for (i = 0; i < len; i++) {
freq[(unsigned char)str[i]]++;
}
// 打印各个字符的出现频率
for (i = 0; i < 256; i++) {
if (freq[i] > 0) {
printf("%c:%d\n", i, freq[i]);
}
}
// 构建哈夫曼树
struct huffman_node *root = build_huffman_tree(freq);
// 对字符串进行哈夫曼编码
printf("哈夫曼编码:");
huffman_encode(str, root);
putchar('\n');
return 0;
}
```
阅读全文