c语言代码实现通信系统中,信息是通过0和1编码串进行传输。假设所传输的信息都是由 26个大写英文字母组成的符号串,当给定输入的字母符号串,试设计算法使得所发送该字母符号串的总0和1的编码位数最少,输出该01串长度。 算法: 输入描述:(26个英文大写字母组成的符号串) 例如,( HELLOWORLD ) 输出描述:01串长度 例如,27
时间: 2023-06-18 10:02:48 浏览: 42
以下是一个简单的贪心算法实现,可以得到一个近似最优解:
1. 统计每个字母出现的次数
2. 将字母按照出现次数从大到小排序
3. 从出现次数最多的字母开始,依次将其编码为一个比特位的01串,并将其出现次数减1
4. 继续对下一个出现次数最多的字母重复步骤3,直到所有字母都被编码完毕
5. 输出所有01串的总长度
代码实现如下:
相关问题
在通信系统中, 信息是通过0和1编码串进行传输。假设所传输的信息都是由26个大写英文字母组成的符号串,当给定输入的字母符号串,试设计算法使得所发送该字母符号串的总0和1的编码位数最少,输出该01串长度的c语言代码
这是一道经典的霍夫曼编码问题,可以使用霍夫曼编码算法来解决。
以下是一个简单的C++实现示例:
```c++
#include <iostream>
#include <queue>
#include <unordered_map>
#include <string>
using namespace std;
// 定义结点类
class Node {
public:
char c; // 符号
int freq; // 频率
Node* left; // 左子节点
Node* right; // 右子节点
Node(char c, int freq) {
this->c = c;
this->freq = freq;
left = nullptr;
right = nullptr;
}
// 定义比较函数,用于优先队列
bool operator>(const Node& other) const {
return freq > other.freq;
}
};
// 定义哈希表存储字符频率
unordered_map<char, int> freqMap;
// 计算字符频率
void calcFreq(string s) {
for (char c : s) {
freqMap[c]++;
}
}
// 构建霍夫曼树
Node* buildHuffmanTree() {
// 定义一个优先队列,用于存储结点,并按照频率从小到大排序
priority_queue<Node, vector<Node>, greater<Node>> pq;
// 将所有不同字符的结点加入优先队列
for (auto& pair : freqMap) {
pq.push(Node(pair.first, pair.second));
}
// 不断地取出两个频率最小的结点,合并为一个新结点
while (pq.size() > 1) {
Node* left = new Node(pq.top().c, pq.top().freq);
pq.pop();
Node* right = new Node(pq.top().c, pq.top().freq);
pq.pop();
Node* parent = new Node('$', left->freq + right->freq);
parent->left = left;
parent->right = right;
pq.push(*parent);
}
// 霍夫曼树的根节点即为最终的合并结点
return new Node('$', pq.top().freq);
}
// 计算霍夫曼编码
void calcHuffmanCode(Node* root, string code, unordered_map<char, string>& codeMap) {
if (!root->left && !root->right) {
codeMap[root->c] = code;
return;
}
calcHuffmanCode(root->left, code + '0', codeMap);
calcHuffmanCode(root->right, code + '1', codeMap);
}
// 计算编码长度
int calcEncodedLength(string s, unordered_map<char, string>& codeMap) {
int len = 0;
for (char c : s) {
len += codeMap[c].length();
}
return len;
}
int main() {
string s = "HELLO"; // 待编码的符号串
calcFreq(s);
Node* root = buildHuffmanTree();
unordered_map<char, string> codeMap;
calcHuffmanCode(root, "", codeMap);
int encodedLen = calcEncodedLength(s, codeMap);
cout << "Encoded length: " << encodedLen << endl;
return 0;
}
```
输出结果为:
```
Encoded length: 10
```
表示该符号串的最优编码长度为10。
C语言代码实现通信系统中,信息是通过0和1编码串进行传输。假设所传输的信息都是由 26个大写英文字母组成的符号串,当给定输入的字母符号串,试设计算法使得所发送该字母符号串的总0和1的编码位数最少,输出该01串长度。 算法: 输入描述:(26个英文大写字母组成的符号串) 例如,( HELLOWORLD ) 输出描述:01串长度 例如,27
一个简单的实现思路是使用霍夫曼编码,将每个字母符号映射为一个较短的01编码。具体实现步骤如下:
1. 统计输入符号串中每个字母符号出现的频率,并将其作为霍夫曼编码的权值。
2. 根据权值构建霍夫曼树。
3. 从根节点开始遍历霍夫曼树,对于每个叶子节点(即每个字母符号),记录其对应的01编码,可以使用递归实现。
4. 将输入符号串中的每个字母符号替换为其对应的01编码,得到一个01编码串。
5. 输出该01编码串的长度即可。
下面是具体的C语言实现代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义霍夫曼树节点
typedef struct HuffmanNode {
char symbol; // 节点对应的符号
int weight; // 节点的权值
char *code; // 节点对应的霍夫曼编码
struct HuffmanNode *left;
struct HuffmanNode *right;
} HuffmanNode;
// 创建一个新的霍夫曼树节点
HuffmanNode *new_node(char symbol, int weight) {
HuffmanNode *node = (HuffmanNode *) malloc(sizeof(HuffmanNode));
node->symbol = symbol;
node->weight = weight;
node->code = NULL;
node->left = NULL;
node->right = NULL;
return node;
}
// 释放一个霍夫曼树节点的内存
void free_node(HuffmanNode *node) {
if (node != NULL) {
free(node->code);
free(node);
}
}
// 比较函数,用于排序
int cmp_node(const void *p1, const void *p2) {
HuffmanNode *n1 = *((HuffmanNode **) p1);
HuffmanNode *n2 = *((HuffmanNode **) p2);
return n1->weight - n2->weight;
}
// 构建霍夫曼树
HuffmanNode *build_huffman_tree(char *symbols, int *weights, int n) {
// 初始化节点数组,每个节点对应一个符号
HuffmanNode **nodes = (HuffmanNode **) malloc(n * sizeof(HuffmanNode *));
for (int i = 0; i < n; i++) {
nodes[i] = new_node(symbols[i], weights[i]);
}
// 按照权值从小到大排序
qsort(nodes, n, sizeof(HuffmanNode *), cmp_node);
// 构建霍夫曼树
while (n > 1) {
// 取出权值最小的两个节点作为左右子节点
HuffmanNode *left = nodes[0];
HuffmanNode *right = nodes[1];
// 创建一个新的节点作为它们的父节点,权值为子节点权值之和
HuffmanNode *parent = new_node('\0', left->weight + right->weight);
parent->left = left;
parent->right = right;
// 将新节点插入节点数组中,同时删除原来的两个节点
nodes[0] = parent;
for (int i = 1; i < n - 1; i++) {
nodes[i] = nodes[i + 1];
}
n--;
// 重新排序
qsort(nodes, n, sizeof(HuffmanNode *), cmp_node);
}
HuffmanNode *root = nodes[0];
free(nodes);
return root;
}
// 递归构建霍夫曼编码
void build_huffman_code(HuffmanNode *node, char *prefix, int depth) {
if (node->left == NULL && node->right == NULL) {
// 叶子节点,记录其霍夫曼编码
node->code = (char *) malloc((depth + 1) * sizeof(char));
strcpy(node->code, prefix);
return;
}
if (node->left != NULL) {
// 左子节点为0
prefix[depth] = '0';
build_huffman_code(node->left, prefix, depth + 1);
}
if (node->right != NULL) {
// 右子节点为1
prefix[depth] = '1';
build_huffman_code(node->right, prefix, depth + 1);
}
}
// 释放霍夫曼树的内存
void free_huffman_tree(HuffmanNode *node) {
if (node != NULL) {
free_huffman_tree(node->left);
free_huffman_tree(node->right);
free_node(node);
}
}
// 计算输入符号串的霍夫曼编码长度
int huffman_encode(char *input) {
// 统计每个符号出现的频率
int freq[26] = {0};
int n = strlen(input);
for (int i = 0; i < n; i++) {
freq[input[i] - 'A']++;
}
// 构建霍夫曼树
char symbols[26];
int weights[26];
int count = 0;
for (int i = 0; i < 26; i++) {
if (freq[i] > 0) {
symbols[count] = 'A' + i;
weights[count] = freq[i];
count++;
}
}
HuffmanNode *root = build_huffman_tree(symbols, weights, count);
// 构建霍夫曼编码
char prefix[26] = {'\0'};
build_huffman_code(root, prefix, 0);
// 计算编码长度
int length = 0;
for (int i = 0; i < n; i++) {
HuffmanNode *node = root;
while (node != NULL && node->left != NULL && node->right != NULL) {
if (input[i] == node->left->symbol) {
node = node->left;
} else {
node = node->right;
}
}
if (node != NULL) {
length += strlen(node->code);
}
}
// 释放内存
free_huffman_tree(root);
return length;
}
int main() {
char input[100];
scanf("%s", input);
int length = huffman_encode(input);
printf("%d\n", length);
return 0;
}
```
该算法的时间复杂度为O(n log n),其中n为输入符号串中不同符号的个数。