帮忙改正一下霍夫曼解码算法

roooot 2008-06-04 04:24:12
注:bian数组中的字符是用霍夫曼编码求出的,源码为abcdabcd,其中a的编码为110,b为111,c为10,d为0。
算法的思想是先取一个编码序列中的字符,然后与abcd的字符编码相比,看看是否匹配,如果匹配就跳出里层循环,继续取下一个编码序列中的字符重复上述过程;如果不匹配,就在取出一个编码序列中的字符,看看这两个字符是否与abcd的编码之一匹配,大致就是这样。
但是执行结果不是abcdabcd,请高手帮忙指出一下程序或者算法中的错误,谢谢,对了,我是用vc++6.0编的程序



# include <stdio.h>
# include <string.h>
main()
{
int i,k,j=0,w,r;
char bian[30]={'1','1','0','1','1','1','1','0','0','1','1','0','1','1','1','1','0','0'};
char a[3]={'1','1','0'};/*a的霍夫曼编码*/
char b[3]={'1','1','1'};/*b的霍夫曼编码*/
char c[3]={'1','0'};/*c的霍夫曼编码*/
char d[3]={'0'};/*d的霍夫曼编码*/
char temp[3],shou[8];
r=strlen(bian);
for(i=0;i<r;)/*外层循环用于控制解码进度*/
{
for(k=0;k<3;k++)/*里层用于具体解析每个字符编码*/
{
w=i+k;
temp[k]=bian[w];
if(temp[3]==a[3])/*判断编码是否为a*/
{
shou[j]='a';/*shou数组用于存储解析出来的字符*/
j++;
i=i+k+1;
break;/*如果解析成功就跳出里层循环,继续解析下一个编码*/
}
else if(temp[3]==b[3])/*判断编码是否为b*/
{
shou[j]='b';
j++;
i=i+k+1;
break;
}
else if(temp[3]==c[3])/*判断编码是否为c*/
{
shou[j]='c';
j++;
i=i+k+1;
break;
}
else if(temp[3]==d[3])/*判断编码是否为d*/
{
shou[j]='d';
j++;
i=i+k+1;
break;
}
else
continue;/*如果都不是就再取出一个编码,再与abcd的字符编码相比*/
}
}
for(i=0;i<8;i++)
printf("%c",shou[i]);
}

...全文
218 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
roooot 2008-06-05
  • 打赏
  • 举报
回复
谢谢各位的帮忙,小弟的霍夫曼编码程序终于完成了
  • 打赏
  • 举报
回复
没研究过,学习了~
野男孩 2008-06-05
  • 打赏
  • 举报
回复

# include <stdio.h>
# include <string.h>
# include <conio.h>
main()
{
int i,k,j=0,w,r;
char bian[30]={'1','1','0','1','1','1','1','0','0','1','1','0','1','1','1','1','0','0'};
char a[3]={'1','1','0'};/*a的霍夫曼编码*/
char b[3]={'1','1','1'};/*b的霍夫曼编码*/
char c[3]={'1','0'};/*c的霍夫曼编码*/
char d[3]={'0'};/*d的霍夫曼编码*/
char temp[3]={'\0','\0','\0'},shou[8];
r=strlen(bian);
for(i=0;i<r;)/*外层循环用于控制解码进度*/
{
temp[0] = temp[1] = temp[2] = 0;
for(k=0;k<3;k++)/*里层用于具体解析每个字符编码*/
{
w=i+k;
temp[k]=bian[w];
if(strncmp(temp,a,3)==0)/*判断编码是否为a*/
{
shou[j]='a';/*shou数组用于存储解析出来的字符*/
j++;
i=i+k+1;
break;/*如果解析成功就跳出里层循环,继续解析下一个编码*/
}
else if(strncmp(temp,b,3)==0)/*判断编码是否为b*/
{
shou[j]='b';
j++;
i=i+k+1;
break;
}
else if(strncmp(temp,c,2)==0)/*判断编码是否为c*/
{
shou[j]='c';
j++;
i=i+k+1;
break;
}
else if(strncmp(temp,d,1)==0)/*判断编码是否为d*/
{
shou[j]='d';
j++;
i=i+k+1;
break;
}
else
continue;/*如果都不是就再取出一个编码,再与abcd的字符编码相比*/
}
}
for(i=0;i<8;i++)
printf("%c",shou[i]);
return 0;
}


roooot 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 k2eats 的回复:]
你的程序越界操作
其次,编码是不是就错了:源码为abcdabcd,其中a的编码为110,b为111,c为10,d为0??????
[/Quote]

编码确实是abcdabcd啊
gezichong 2008-06-04
  • 打赏
  • 举报
回复
程序输出:
abdcbd
Press any key to continue
gezichong 2008-06-04
  • 打赏
  • 举报
回复
按照LZ的方法,是不可能判断出来的,因为LZ只判断了最后一个数字编码,而且在程序中是已经越界的.

按照LZ的方法,我把程序修改了一下,可以实现LZ的功能,不过,我认为哈夫曼编码好像不是这样实现的.

建议到网上搜一下.
gezichong 2008-06-04
  • 打赏
  • 举报
回复
修改如下:

#include <stdio.h>
#include <string.h>

main()
{
int i,k,j=0,w,r;
char bian[30]={'1','1','0','1','1','1','1','0','0','1','1','0','1','1','1','1','0','0'};
char a[3]={'1','1','0'};/*a的霍夫曼编码*/
char b[3]={'1','1','1'};/*b的霍夫曼编码*/
char c[3]={'1','0'};/*c的霍夫曼编码*/
char d[3]={'0'};/*d的霍夫曼编码*/
char temp[3],shou[8];
r=strlen(bian);
for(i=0;i<r;i++)/*外层循环用于控制解码进度*/
{
for(k=0;k<3;k++)/*里层用于具体解析每个字符编码*/
{
w=i+k;
temp[k]=bian[w];
if(k==0){
if (temp[k] == '1'){ //a,b,c的第一个字符
continue;
}else{
//为d
shou[j]='d';
j++;
i=i+k+1;
break;
}
}
if (k==1){
if (temp[k]=='1'){//a,b
continue;
}else{
//为c
shou[j]='c';
j++;
i=i+k+1;
break;
}

}
if (k==2){
if (temp[k]=='1'){//b

shou[j]='b';
j++;
i=i+k+1;
break;
}else{
//a
shou[j]='a';
j++;
i=i+k+1;
break;
}
}

}
}

for(i=0;i<j;i++)
printf("%c",shou[i]);
printf("\n");
}

K行天下 2008-06-04
  • 打赏
  • 举报
回复
你的程序越界操作
其次,编码是不是就错了:源码为abcdabcd,其中a的编码为110,b为111,c为10,d为0??????
0黄瓜0 2008-06-04
  • 打赏
  • 举报
回复
应该用构造的树来解析编码.
比如你构造霍夫曼树时规定向左走为0,向右走为1. 不断的从根结点走到叶子结点就得到相应编码的解了.
iu_81 2008-06-04
  • 打赏
  • 举报
回复
bian[w]也可能越界
iu_81 2008-06-04
  • 打赏
  • 举报
回复
temp[3]==a[3]
temp[3]==b[3]
temp[3]==c[3]
temp[3]==d[3]
============
a,b,c,d已经越界

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧