信源熵的计算
程序代码:#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 编辑 ]






