统计字符串出现的次数并输出哈夫曼编码c语言
时间: 2023-11-15 08:06:39 浏览: 46
这里提供一个使用哈希表统计字符串出现次数的C语言示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH_TABLE_SIZE 100 // 哈希表的最大长度
typedef struct node {
char* key; // 键值
int value; // 出现次数
struct node* next; // 指向下一个节点的指针
} Node;
Node* hashTable[MAX_HASH_TABLE_SIZE]; // 哈希表
int tableSize = 0; // 实际哈希表的长度
// 哈希函数
int hash(char* key) {
int hashValue = 0;
while (*key != '\0') {
hashValue = (hashValue << 5) + *key++; // 每个字符左移5位再相加
}
return hashValue % MAX_HASH_TABLE_SIZE;
}
// 插入一个节点到哈希表中
void insert(char* key) {
int index = hash(key);
Node* ptr = hashTable[index];
while (ptr != NULL) {
if (strcmp(ptr->key, key) == 0) { // 如果找到了相同的键值,增加出现次数
++ptr->value;
return;
}
ptr = ptr->next;
}
// 如果没有找到相同的键值,创建一个新的节点并插入到链表头部
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->key = key;
newNode->value = 1;
newNode->next = hashTable[index];
hashTable[index] = newNode;
++tableSize;
}
// 遍历哈希表,输出统计结果
void printHashTable() {
printf("Result (key, value):\n");
for (int i = 0; i < MAX_HASH_TABLE_SIZE; ++i) {
Node* ptr = hashTable[i];
while (ptr != NULL) {
printf("('%s', %d)\n", ptr->key, ptr->value);
ptr = ptr->next;
}
}
}
int main() {
// 读入字符串
char str[100];
printf("Please input the string:\n");
fgets(str, sizeof(str), stdin);
str[strlen(str)-1] = '\0'; // 去掉换行符
// 把字符串按照空格分割成多个单词
char* word = strtok(str, " ");
while (word != NULL) {
insert(word);
word = strtok(NULL, " ");
}
printHashTable();
return 0;
}
```
关于哈夫曼编码,可以参考下面的C语言示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NODE_NUM 200 // 最大节点数
#define MAX_CODE_LEN 100 // 最大编码长度
// 哈夫曼树的节点
typedef struct node {
int weight; // 权值
int parent, lchild, rchild; // 指向父节点和左右子节点的指针
} HNode;
// 编码表的一个项
typedef struct code {
char data; // 字符
char code[MAX_CODE_LEN]; // 对应的哈夫曼编码
} HCode;
// 创建哈夫曼树
void createHuffmanTree(HNode* tree, int n) {
for (int i = 0; i < 2*n-1; ++i) {
tree[i].parent = -1;
tree[i].lchild = -1;
tree[i].rchild = -1;
}
for (int i = 0; i < n; ++i) {
printf("Please input the weight of node %d:\n", i+1);
scanf("%d", &(tree[i].weight));
}
for (int i = n; i < 2*n-1; ++i) {
int s1 = -1, s2 = -1; // 找到权值最小的两个节点
for (int j = 0; j < i; ++j) {
if (tree[j].parent == -1) {
if (s1 == -1 || tree[j].weight < tree[s1].weight) {
s2 = s1;
s1 = j;
} else if (s2 == -1 || tree[j].weight < tree[s2].weight) {
s2 = j;
}
}
}
tree[s1].parent = i;
tree[s2].parent = i;
tree[i].lchild = s1;
tree[i].rchild = s2;
tree[i].weight = tree[s1].weight + tree[s2].weight;
}
}
// 从叶子节点遍历哈夫曼树,生成编码表
void createHuffmanCode(HNode* tree, HCode* hcodes, int n) {
char buffer[MAX_CODE_LEN]; // 缓冲区
for (int i = 0; i < n; ++i) {
int current = i;
int parent = tree[current].parent;
int codeLen = 0;
while (parent != -1) { // 遍历到根节点
if (tree[parent].lchild == current) { // 左子节点,则在编码前面添加0
buffer[codeLen++] = '0';
} else if (tree[parent].rchild == current) { // 右子节点,则在编码前面添加1
buffer[codeLen++] = '1';
}
current = parent;
parent = tree[current].parent;
}
buffer[codeLen] = '\0';
hcodes[i].data = (char)(i+1); // 字符,这里设为i+1
strcpy(hcodes[i].code, strrev(buffer)); // 将缓冲区中的0和1翻转,得到正确的编码
}
}
int main() {
// 创建哈夫曼树
HNode* tree = (HNode*)malloc(MAX_NODE_NUM * sizeof(HNode));
printf("Please input the number of leaf nodes:\n");
int n;
scanf("%d", &n);
createHuffmanTree(tree, n);
// 生成哈夫曼编码
HCode* hcodes = (HCode*)malloc(n * sizeof(HCode));
createHuffmanCode(tree, hcodes, n);
// 输出编码表
printf("Huffman coding table:\n");
for (int i = 0; i < n; ++i) {
printf("%c: %s\n", hcodes[i].data, hcodes[i].code);
}
return 0;
}
```
注意:这里用到了一个strrev()函数,请自行实现。