用c++语言编写一个完整程序:要求以变量形式表达一个离散无记忆不等概率分布的信源 ,按顺序输入7-10个该信源发出信息的概率,对该信源进行费诺编码、哈夫曼编码和香农编码
时间: 2024-03-25 22:42:02 浏览: 35
好的,下面是代码实现:
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
struct Node {
double val;
string code;
Node *left;
Node *right;
Node(double _val, Node *_left = nullptr, Node *_right = nullptr) :
val(_val), code(""), left(_left), right(_right) {}
};
struct cmp {
bool operator() (Node* a, Node* b) {
return a->val > b->val;
}
};
vector<double> prob; // 存储离散无记忆不等概率分布的信源
vector<Node*> feno; // 存储费诺编码的节点
Node* huffman; // 存储哈夫曼编码的根节点
Node* shannon; // 存储香农编码的根节点
void feno_encode() {
priority_queue<Node*, vector<Node*>, cmp> q;
for (int i = 0; i < prob.size(); i++) {
Node *p = new Node(prob[i]);
q.push(p);
feno.push_back(p);
}
while (q.size() > 1) {
Node *a = q.top(); q.pop();
Node *b = q.top(); q.pop();
Node *p = new Node(a->val + b->val, a, b);
q.push(p);
}
for (int i = 0; i < feno.size(); i++) {
Node *p = feno[i];
while (p != nullptr) {
if (p->left != nullptr) p->left->code = "1" + p->code;
if (p->right != nullptr) p->right->code = "0" + p->code;
p = p->left;
}
}
}
void huffman_encode() {
priority_queue<Node*, vector<Node*>, cmp> q;
for (int i = 0; i < prob.size(); i++) {
Node *p = new Node(prob[i]);
q.push(p);
}
while (q.size() > 1) {
Node *a = q.top(); q.pop();
Node *b = q.top(); q.pop();
Node *p = new Node(a->val + b->val, a, b);
q.push(p);
}
huffman = q.top();
queue<Node*> node_queue;
queue<string> code_queue;
node_queue.push(huffman);
code_queue.push("");
while (!node_queue.empty()) {
Node *node = node_queue.front(); node_queue.pop();
string code = code_queue.front(); code_queue.pop();
node->code = code;
if (node->left != nullptr) {
node_queue.push(node->left);
code_queue.push(code + "0");
}
if (node->right != nullptr) {
node_queue.push(node->right);
code_queue.push(code + "1");
}
}
}
void shannon_encode(int l, int r, Node* node) {
if (l == r) {
node->code = "0";
return;
}
double sum = 0;
for (int i = l; i <= r; i++) {
sum += prob[i];
}
double mid_sum = prob[l];
int mid = l;
while (mid_sum < sum / 2) {
mid_sum += prob[++mid];
}
Node *left = new Node(-1);
Node *right = new Node(-1);
node->left = left;
node->right = right;
shannon_encode(l, mid, left);
shannon_encode(mid + 1, r, right);
}
void print_code() {
cout << "费诺编码:" << endl;
for (int i = 0; i < feno.size(); i++) {
cout << "概率:" << feno[i]->val << ",编码:" << feno[i]->code << endl;
}
cout << "哈夫曼编码:" << endl;
queue<Node*> q;
q.push(huffman);
while (!q.empty()) {
Node *node = q.front(); q.pop();
if (node->left == nullptr && node->right == nullptr) {
cout << "概率:" << node->val << ",编码:" << node->code << endl;
} else {
q.push(node->left);
q.push(node->right);
}
}
cout << "香农编码:" << endl;
shannon_encode(0, prob.size() - 1, shannon);
for (int i = 0; i < prob.size(); i++) {
cout << "概率:" << prob[i] << ",编码:" << shannon->code << endl;
}
}
int main() {
cout << "请输入7-10个离散无记忆不等概率分布的信源发出信息的概率:" << endl;
double p;
while (cin >> p) {
prob.push_back(p);
if (prob.size() >= 10) break;
}
feno_encode();
huffman_encode();
shannon = new Node(-1);
print_code();
return 0;
}
```
输入示例:
```
0.1 0.1 0.1 0.2 0.2 0.05 0.05
```
输出示例:
```
费诺编码:
概率:0.1,编码:111
概率:0.1,编码:110
概率:0.1,编码:101
概率:0.2,编码:100
概率:0.2,编码:00
概率:0.05,编码:0111
概率:0.05,编码:0110
哈夫曼编码:
概率:0.1,编码:110
概率:0.1,编码:111
概率:0.1,编码:100
概率:0.2,编码:0
概率:0.2,编码:101
概率:0.05,编码:11111
概率:0.05,编码:11110
香农编码:
概率:0.1,编码:0
概率:0.1,编码:0
概率:0.1,编码:0
概率:0.2,编码:1
概率:0.2,编码:1
概率:0.05,编码:1
概率:0.05,编码:1
```