信源熵的计算
程序代码:
#include <stdio.h> #include <stdlib.h> #include <math.h> //把字母统一对应26个数字 int charge(char c) { int n; if (c>=65&&c<=90) { c+=32; } if (c>=97 && c<=122) { n=c-97; return n; } else return -1; } void main() { int count[26][26]={0}; char zifu1,zifu2; int i,n,m,j; int sum=0; FILE *fp; if ((fp = fopen("file.txt","rb")) == NULL) { printf("can't open file!\n"); exit(0); } while(!feof(fp)) { zifu1 = fgetc(fp); n =charge(zifu1); if (n!=-1) { zifu2 = fgetc(fp); m = charge(zifu2); if (m!=-1) { count[n][m]++; fseek(fp, -1, 1); } } } fclose(fp); for (i =0; i<26; i++) { for ( j=0; j<26; j++) { sum+=count[i][j]; } } printf("the number of all the code is %d\n", sum); float q = (float)sum; for (i =0;i<26;i++) for (j=0;j<26;j++) { if (j%3 == 0) printf("\n"); printf("%c%c,%4d %6.5f%% ", i+97, j+97, count[i][j], count[i][j]*100/q); } float sum1=0; printf("\n"); for(i=0;i<26;i++) for(j=0;j<26;j++) if (count[i][j]) sum1 = sum1+(float)( (count[i][j]/q) * log10(1/(double)(count[i][j]/q))/log10( (double)(2) ) ); printf("\n信息熵为: H(X)=%f\n", sum1/2); float H0=sum1/2; float H2=3.32; printf("信源的剩余度为: R=%f",1-H2/H0); }一维信源熵:
程序代码:
#include <stdio.h> #include <math.h> #include <stdlib.h> int charge(char c) { int n; if (c>=65 && c<=90) c+=32; if (c>=97 && c<=122) { n=c-97; return n; } else return -1; } int main() { int count[26] = {0}; char ch; int sum=0; int i; int j; float fSum=0; float fH=0; FILE *fp; if ( (fp = fopen("file.txt", "rb")) == NULL) { printf("Can't open file to read!\n"); exit(0); } while(!feof(fp)) { ch = fgetc(fp); if (-1 != charge(ch)) count[charge(ch)]++; } for (i = 0; i<26 ; i++) sum += count[i]; printf("the number of all the code is %d\n", sum); fSum=(float)sum; for (i = 0; i<26; i++) { if (i%3==0) printf("\n"); printf("%c, %5d %6.5f%% ", i+97, count[i], count[i]/fSum); fH += (float)((count[i]/fSum)* log10((double)1/(count[i]/fSum)) / log10((double)(2))); } printf("\n\n一维信源熵为:H(X) = %f\n", fH); printf("\n一维信源剩余度:R = %f\n", 1-4.03/fH); return 0; } //香浓编码 #include<stdio.h> #include<iostream.h> #include<math.h> #define MAX 7 double P[MAX]={0.01, 0.10, 0.15, 0.17,0.18, 0.19, 0.20},Pax[MAX],machang[MAX]; int main() { double temp; //递减排序(冒泡排序) for(int a=1;a<MAX;a++) { for(int i=0;i<MAX-a;i++) if(P[i]<P[i+1]) { temp=P[i]; P[i]=P[i+1]; P[i+1]=temp; } } //输出消息概率 for(int i=0;i<MAX;i++) cout<<P[i]<<" "; cout<<endl; //累加概率 for(i=0;i<MAX;i++) { Pax[0]=0.0; Pax[i+1] = Pax[i] + P[i]; } cout << "概率累加和为:" << endl; //输出对应的累加概率 for ( i = 0; i<MAX; i++) { cout << Pax[i] << " "; } cout << endl; //求每个消息的码长 for (i=0; i<MAX; i++) { double m = log(1/P[i])/log(2); if (m -int(m) == 0) machang[i] = log(1/P[i])/log(2); else machang[i] = int(m) +1; cout << P[i] << "的码长为:" << machang[i] << endl; } //小数点转化为二进制 for (i=0; i<MAX; i++) { cout<<"消息概率" << P[i] <<"的二进制码组为: "; for (int j=0;j<machang[i];j++) { int n=int(Pax[i]*2); cout << n; //判断Pax[i]*2是否>1 if ( (Pax[i]*2-1)>=0) Pax[i] = Pax[i]*2 -1;//大于1就减1 else Pax[i] = Pax[i]*2;//否则就称2 } cout << endl; } cout << endl; return 0; } Huffma编码 #include <stdio.h> #include <stdlib.h> #define n 5 #define m 2*n-1 //位域结构体 typedef struct Bit {//只能放0和1 unsigned int a:1;//放0或1 }Mybit; typedef struct tree { float weight; int lChild; int rChild; int parent; Mybit bit; struct tree()//初始化树 { weight = 0.0; lChild = -1; rChild = -1; parent = -1; bit.a = 1; } }Huffman; typedef int elemtype;//定义元素类型 typedef struct stack { elemtype data[n-1];// int top; }Stack; void TowSmallNode(Huffman tree[],int k,int *lsmall, int *rsmall) { int i = 0; int temp; *lsmall = *rsmall = 0; for ( i = 0; i<k; i++)//找到最小权的下标 { if(tree[i].parent == -1) { if(tree[*lsmall].weight >= tree[i].weight || tree[*lsmall].parent != -1) { *lsmall = i; } } } for (i=0; i<k; i++)//找到第二小的权的下标 { if(tree[i].parent == -1 && i != *lsmall) { if(tree[*rsmall].weight >= tree[i].weight) { *rsmall = i; } else if ( (*lsmall == 0 && *rsmall ==0) || tree[*rsmall].parent != -1) { *rsmall = i; } } } //判断哪个做右边哪个做左边 if (tree[*rsmall].lChild !=-1 && tree[*lsmall].lChild == -1 )//有孩子那边做为左边 { temp = *rsmall; *rsmall = *lsmall; *lsmall = temp; } } void CreateTree(Huffman tree[]) { int i = 0; int lsmall = 0; int rsmall = 0; float w; printf("请输入消息的概率:\n"); for (i = 0; i<n; i++)//输入叶子 { scanf("%f", &w); tree[i].weight = w; } for (i=n; i<m; i++)//剩下的节点 { TowSmallNode(tree,i, &lsmall, &rsmall);//找出最小权的两个标 tree[i].lChild = lsmall;//左孩子 tree[i].rChild = rsmall;//右孩子 tree[i].weight = tree[lsmall].weight + tree[rsmall].weight;//两个最小权值相加 tree[lsmall].parent = i; tree[rsmall].parent = i; tree[lsmall].bit.a = 0;//是左边的就放二进制的0 } } //置空栈 void setNull(Stack *s) { s ->top = -1; return ; } //进栈 void push(Stack *s, elemtype x) { s ->top++; s ->data[s->top] = x; return; } //出栈 elemtype pop(Stack *s) { s ->top--; return (s ->data[s->top+1]); } // int main() { Huffman tree[m]; CreateTree(tree); int i =0; int k; Stack *s = (Stack*)malloc(sizeof(Stack));//分配栈空间 for (i =0 ; i<n; i++) { k = i; setNull(s);//置栈为空 while(tree[k].parent !=-1) { push(s, tree[k].bit.a);//进栈 k = tree[k].parent ; } //出栈 printf("消息的概率为%.2f的二进制码为:",tree[i].weight); while(s->top != -1) { printf("%d", pop(s));//输出二进制码 } printf("\n"); } free(s);//释放空间 return 0; }
[ 本帖最后由 ycc892009 于 2010-11-11 20:47 编辑 ]