N=input('N=')%输入信源符号的个数
s=0l=0H=0
for i=1:N
fprintf('第%d个',i)
p(i)=input('p=')%输入信源符号概率分布矢量,p(i)<1
if p(i)<=0
error('不符合概率分布')
end
s=s+p(i)
H=H+(- p(i)*log2(p(i)))%计猛茄陪算信源信息熵
end
if (s<=0.999999||s>=1.000001)
error('不符合概率分布')
end
tic
for i=1:N-1 %按概率分布大小对信源排序
for j=i+1:N
if p(i)<p(j)
m=p(j)p(j)=p(i)p(i)=m
end
end
end
x=f1(1,N,p,1)
for i=1:N %计算平均码长
L(i)=length(find(x(i,:)))
l=l+p(i)*L(i)
end
n=H/l%计算编码效枝蠢率
fprintf('按概率降序排列的码字:\n')
disp(x) %显示按概率降序排列的码字
fprintf('平均码长:\n')
disp(l)% 显示平均码长
fprintf('信源信息熵:\n')
disp(H)%显示信源信息熵
fprintf('编码效率:\n')
disp(n) %显示编码效率
fprintf('计算耗时time= %f\n',toc)
再建立两个M文件:%函数f1存放于f1.m
function x=f1(i,j,p,r)
global x
x=char(x)
if(j<=i)
return
else
q=0
for t=i:j %对于区间[i,j]自上而下求累加概率值
q=p(t)+qy(t)=q
end
for t=i:j%把所有自上而下的累加概率值与该区间总概率值减该累加概率值之差取绝对值存在一数组
v(t)=abs(y(t)-(q-y(t)))
end
for t=i:j
if(v(t)==min(v)) %求该数组中最小的一个值来确定分界点位置
for k=i:t%赋值码字
x(k,r)='0'
end
for k=(t+1):j
x(k,r)='1'
end
d=t
f1(i,d,p,r+1)%递归调用及相互调用
f2(d+1,j,p,r+1)
f1(d+1,j,p,r+1)
f2(i,d,p,r+1)
else
end
end
end
return第二个:%函数f2存放于f2.m
function x=f2(i,j,p,r)
global x
x=char(x)
if(j<=i)
return
else
q=0
for t=i:j %对于区间[i,j]自上而下求累加概率值
q=p(t)+qy(t-i+1)=q
end
for t=1:j-(i-1)%把所有自上而下的累加概率值与该区间总概率值减该累加概率值之差取绝对值存在一数组
v(t)=abs(y(t)-(q-y(t)))
end
for t=1:j-(i-1)
if(v(t)==min(v)) %求该数组中最小的一个值来确定分界点位置
d=t+i-1
for k=i:d %赋值码字
x(k,r)='0'
end
for k=(d+1):j
x(k,r)='1'
end
f2(d+1,j,p,r+1)%递归调用及相互调用
f1(i,d,p,r+1)
f2(i,d,p,r+1)
f1(d+1,j,p,r+1)
else
end
end
end
return
#include <stdio.h>#include <malloc.h>
#include <string.h>
struct huffmantree
{
char zifu
int weight
int parent,lchild,rchild
}
struct huffmancode
{
char cd[50]
int start
}
int *select(struct huffmantree HT[],int n,int s[])
{
int i,min1,min2
min1 = 32767
min2 = 32767
for (i = 1i <= n++ i)
{
if (HT[i].weight<min1&&HT[i].parent==0)
{
min1 = HT[i].weight
s[0] = i
}
}
for (i = 1i <= n++ i)
{
if (HT[i].weight<min2 &&HT[i].parent == 0&&HT[i].weight >= min1&&i != s[0])
{
min2 = HT[i].weight
s[1] = i
}
}
return s
}
void createhuffmantree(struct huffmantree HT[],struct huffmancode HC[],char zi[],int w[],int n)
{
FILE *fp
int m,i,s[2],c,f,end=0,j,k
char linshi[50]
if (n<=1) return
m=2*n-1
fp = fopen ("hfmtree.txt","w+")
for (i=1i<=n++i)
{
HT[i].zifu=zi[i]
HT[i].weight=w[i]
HT[i].parent=0
HT[i].lchild=0
HT[i].rchild=0
}
for (i<=m++i)
{
HT[i].weight=0
HT[i].lchild=0
HT[i].rchild=0
HT[i].parent=0
}
for (i=n+1i<=m++i)
{
select(HT,i-1,s)
HT[s[0]].parent = i
HT[s[1]].parent = i
HT[i].lchild = s[0]
HT[i].rchild = s[1]
HT[i].weight = HT[s[0]].weight + HT[s[1]].weight
}
for (i = 1i <穗哗= m++ i)
{
fprintf(fp,"猜亏行[%d] %d%d%d\n",i,HT[i].parent,HT[i].lchild,HT[i].rchild)
}
for (i = 1i <= n++ i)
{
for (c = i,f = HT[i].parentf != 0c = f,f = HT[f].parent)
{
if (HT[f].lchild == c)
{
linshi[end] = '0'
}
else linshi[end] = '1'
end ++
}
linshi[end] = '\0'
HC[i].start = end
for (j = end-1,k = 0j >= 0j --,k ++)
{
HC[i].cd[k] = linshi[j]
}
HC[i].cd[k] = '\0'空迹
end = 0
}
}
void print(struct huffmantree HT[],struct huffmancode HC[],int n)
{
int i,j
printf("输出哈夫曼编码:\n")
for (i = 1i <= ni ++)
{
printf("%c:",HT[i].zifu)
for (j = 0j <HC[i].startj ++)
{
printf("%c",HC[i].cd[j])
}
printf("\n")
}
}
void printhuffmantree(struct huffmantree HT[],int n)
{
int m,i
m = 2 * n - 1
printf("char----parent----lchild----rchild\n")
for (i = 1i <= m++ i)
{
printf("[%d] %d%d%d\n",i,HT[i].parent,HT[i].lchild,HT[i].rchild)
}
}
int main()
{
FILE *fp
int n,i,w[100],xuanze,j,k=0,x,y=0,p=0,q
char zi[100],a[1000],huffman[1000],yiwen[1000]
struct huffmancode HC[100]
struct huffmantree HT[100]
printf("***************\n 1.建立哈夫曼树\n 2.哈夫曼编码\n 3.哈夫曼译码\n 4.打印哈夫曼树 \n 0.退出\n***************\n")
printf("输入你想要的 *** 作\n")
scanf("%d",&xuanze)
while (xuanze)
{
switch (xuanze)
{
case 1:
printf("输入需要字符的个数\n")
scanf("%d",&n)
printf("输入需要字符的字符和权数\n")
for (i = 1i <= n++ i)
{
getchar()
scanf ("%c %d",&zi[i],&w[i])
}
createhuffmantree(HT,HC,zi,w,n)
break
case 2:
fp = fopen("ToBeTran.txt","w+")
printf("输入你想编码的电文\n")
getchar()
gets(a)
fprintf(fp,"%s",a)
for (i = 0a[i] != '\0'++i)
{
for (j = 1j <= n++j)
{
if (a[i] == HT[j].zifu)
{
for (x = 0HC[j].cd[x] != '\0'++ k,++ x)
{
huffman[k] = HC[j].cd[x]
}
}
}
}
huffman[k] = '\0'
printf("打印哈夫曼编码\n")
for (i = 0i <50++i)
{
for (j = 0j <50++j)
{
printf("%c",huffman[p])
p++
if (p >= k)
{
break
}
}
printf("\n")
if (p >= k)
{
break
}
}
fp = fopen("CodeFile.txt","w+")
fprintf(fp,"%s",huffman)
break
case 3:
for (i = 0huffman[i] != '\0')
{
for (j = 1j <= n++j)
{
q = 0
for (p = 0p <HC[j].start++p)
{
if (huffman[i] == HC[j].cd[p])
{
q ++
i ++
if(p == (HC[j].start - 1))
{
yiwen[y] = HT[j].zifu
y ++
break
}
}
else
{
i = i - q
break
}
}
}
}
yiwen[y] = '\0'
puts(yiwen)
printf("\n")
break
case 4:
printhuffmantree(HT,n)
print(HT,HC,n)
break
case 0:break
}
printf("***************\n 1.建立哈夫曼树\n 2.哈夫曼编码\n 3.哈夫曼译码\n 4.打印哈夫曼树 \n 0.退出\n***************\n")
printf("输入你想要的 *** 作\n")
scanf("%d",&xuanze)
}
return 0
}
这个程序的编码部分只是对于固定的字符串进行编码,也就是说整个程序的编码都是对于同一个字符串进行的,所以,你如果想对任意的字符串进行编码的话,需要将编码部分的函数进行修改,也就是说要将编码的字符数组建立成动态的即可。 因为这是我们当时作业要求的,我也就没有多修改。
#include <stdio.h>#include <string.h>
#include<math.h>
int main()//御备是少了main函数,程序里面一定要有main函数的
{
double p[100]//每个信源的概率
int n/镇扮毁/信源个数
int i
double sum=0
scanf("%d",&n)
for(i=0i<ni++)
{
scanf("%lf",&p[i])
sum+=-p[i]*(log(p[i])/log(2.0))
}
printf("%lf\缺吵n",sum)
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)