二进制香农编码C语言实现,香农编码(课程设计)报告.doc

香农编码(课程设计)报告

信息论与编码课程设计

实验报告

课程题目: 香农编码

姓 名: 叶显权

学 号: 7

班 级: 电信10-03班

指导老师: 成凌飞

学 院:电气工程与自动化学院

日 期: 2013年3月28日

设计任务与要求

熟悉运用香农编码,并能通过C语言进行编程,对任意输入消息概率,利用香农编码方法进行编码,并计算信源熵和编码效率。

二 . 实验原理

原理:编码的目的是为了优化通信系统。香农编码属于不等长编码,通常将经常出现的消息编成短码,不常出现的消息编成长码。从而提高通信效率。

香农第一定理指出了平均码长与信源之间的关系,同时也指出了可以通过编码使平均码长达到极限值,这是一个很重要的极限定理。

香农第一定理指出,选择每个码字的长度Ki满足下式:

-log2 p(xi)≤ Ki <1-log2 p(xi)

就可以得到这种码。这种编码方法称为香农编码 。

二进制香农码的编码步骤如下:

⑴将信源符号按概率从大到小的顺序排列,

p(a1)≥ p(a2)≥…≥ p(an)

⑵确定满足下列不等式的整数Ki ,

-log2 p(ai)≤ Ki <1-log2 p(ai)

⑶令p(a1)=0,用Pi表示第i个码字的累加概率,

⑷将Pi用二进制表示,并取小数点后Ki位作为符号ai的编码

三.设计思路

二进制香农编码的步骤如下:(1)、将信源符号按概率从大到小的顺序排列(2)、对第j个前的概率进行累加得到pa(aj)(3)、由-logp(ai)ki<1-logp(ai)求得码字长度ki(4)、将pa(aj)用二进制表示,并取小数点后ki位作为符号ai的编码。

设计流程图

输入符号概率

输入符号概率

十进制小数转换成二进制

输出函数

求前J个的累加和

求码长Ki

将信源符号概率从大到小排序

五. 程序及结果

香农编码源程序

#include

#include

#include

#include

class T

{

public:

T() {}

~T();

void Create();

void Coutpxj();

void Coutk();

void Coutz();

void Print();

protected:

int n;

double *p;

double *pxj;

int *k;

double *mz;

};

void T::Create()

{

cout<

cin>>n;

p=new double[n];

cout<

for(int i=0;i

cin>>p[i];

pxj=new double[n];

k=new int[n];

mz=new double[n];

double sum=0.0;

for(i=0;i

sum+=p[i];

if(sum!=1.0)

throw 1;

else

{

for(i=0;i

{

int k=i;

for(int j=i+1;j

if(p[k]

double m=p[i];

p[i]=p[k];

p[k]=m;

}

}

}

T::~T()

{

delete p;

delete pxj;

delete k;

delete mz;

}

void T::Coutpxj()

{

pxj[0]=0;

for(int i=1;i

{

pxj[i]=0;

for(int j=0;j

pxj[i]+=p[j];

}

}

void T::Coutk()

{

for(int i=0;i

{

double d=(-1)*(log(p[i])/log(2));

if(d-(int)d>0) k[i]=(int)d+1;

else k[i]=(int)d;

}

}

void T::Print()

{

cout<

抱歉,我不能提供文档或代码的下载链接,因为这可能侵犯版权。但是,我可以为您提供一个基于C语言的简单示例代码,用于演示如何实现香农编码。请注意,这只是一个示例代码,实际应用中可能需要进行更多的优化和改进。 ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define MAX_SYMBOLS 256 #define MAX_CODE_LEN 256 typedef struct { char symbol; int freq; } SymbolFreq; typedef struct { int code[MAX_CODE_LEN]; int len; } Code; SymbolFreq symbol_freq[MAX_SYMBOLS]; Code huffman_code[MAX_SYMBOLS]; int cmp_symbol_freq(const void *a, const void *b) { return ((SymbolFreq *)b)->freq - ((SymbolFreq *)a)->freq; } void calc_symbol_freq(char *str, int len) { int i; memset(symbol_freq, 0, sizeof(symbol_freq)); for (i = 0; i < len; i++) { symbol_freq[(int)str[i]].symbol = str[i]; symbol_freq[(int)str[i]].freq++; } } void build_huffman_tree(int num_symbols) { int i, j, k, l; int freq[MAX_SYMBOLS * 2]; int left[MAX_SYMBOLS * 2]; int right[MAX_SYMBOLS * 2]; int parent[MAX_SYMBOLS * 2]; int num_nodes = num_symbols * 2 - 1; for (i = 0; i < num_symbols; i++) { freq[i] = symbol_freq[i].freq; left[i] = -1; right[i] = -1; parent[i] = -1; } for (; i < num_nodes; i++) { freq[i] = freq[i-2] + freq[i-1]; left[i] = i-2; right[i] = i-1; parent[i-2] = i; parent[i-1] = i; } for (i = num_nodes-1; i >= 0; i--) { if (parent[i] == -1) { huffman_code[(int)symbol_freq[i].symbol].len = 0; continue; } j = i; k = 0; while (parent[j] != -1) { if (left[parent[j]] == j) { huffman_code[(int)symbol_freq[i].symbol].code[k++] = 0; } else { huffman_code[(int)symbol_freq[i].symbol].code[k++] = 1; } j = parent[j]; } huffman_code[(int)symbol_freq[i].symbol].len = k; for (j = 0, l = k-1; j < l; j++, l--) { int temp = huffman_code[(int)symbol_freq[i].symbol].code[j]; huffman_code[(int)symbol_freq[i].symbol].code[j] = huffman_code[(int)symbol_freq[i].symbol].code[l]; huffman_code[(int)symbol_freq[i].symbol].code[l] = temp; } } } void print_huffman_code(int num_symbols) { int i, j; for (i = 0; i < num_symbols; i++) { printf("%c: ", symbol_freq[i].symbol); for (j = 0; j < huffman_code[(int)symbol_freq[i].symbol].len; j++) { printf("%d", huffman_code[(int)symbol_freq[i].symbol].code[j]); } printf("\n"); } } void encode(char *str, int len) { int i, j; for (i = 0; i < len; i++) { for (j = 0; j < huffman_code[(int)str[i]].len; j++) { printf("%d", huffman_code[(int)str[i]].code[j]); } } printf("\n"); } int main(int argc, char **argv) { char str[1000]; int i, len; printf("Enter the string to encode: "); fgets(str, 1000, stdin); len = strlen(str); if (len > 0 && str[len-1] == '\n') { str[len-1] = '\0'; len--; } calc_symbol_freq(str, len); qsort(symbol_freq, MAX_SYMBOLS, sizeof(SymbolFreq), cmp_symbol_freq); build_huffman_tree(len); print_huffman_code(len); encode(str, len); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值