python字符串转二进制代码_将哈夫曼代码字符串转换为二进制

本文探讨了如何在Python中将含有哈夫曼编码的字符串(如01010101010)转换为实际的二进制表示。问题在于,每个0和1应被视为一位,而不是一个字节。编辑中提到,作者使用int和unichr函数处理字符串,但在处理不同长度的哈夫曼编码时遇到问题,因为它们转换后的整数值字节长度不同,导致读写文件时出现混乱。文章最后给出了代码示例来展示遇到的具体问题。
摘要由CSDN通过智能技术生成

我在如何将huffman编码字符串转换为二进制python时遇到了问题。在

这个问题不涉及哈夫曼算法。在

是这样的:

我可以得到一个编码的huffman字符串,比如01010101010。注意,它是一个字符串。在

但是现在我想把字符串表示保存成真正的二进制。在

在哈夫曼编码的字符串中,每0和1都是一个字节。在

我想要的是每0和1是一个位。在

我如何在python中做到这一点呢?在

编辑1:

请原谅我没有把我的问题描述清楚。在

让我解释一下我目前写0和1到二进制的方法。在

例如,我们可以使用一个代码字符串s='010101010'。在我使用int将其转换为整数

然后使用unichr将其转换为字符串,以便将其写入文件

以二进制模式将字符串写入文件

还要注意的是,我需要阅读文件,以便解码哈夫曼密码。在

所以我的方法是从文件中读取字节

把他们恢复到智力

将int转换为它们的二进制表示字符串。在

解码字符串

在第2步,问题发生了,我变得不知所措。在

因为有些huffman字符串可以很短(比如,10),而有些可以很长(010101010101001)。这会导致它们的int值的字节长度不同(

一些短字符串可能只需要一个字节,而长字符串可能需要两个甚至更多

)在

以下代码说明了我的问题:ss=['010101','10010101010']

# first one is short and takes only one byte in its int value

# second one is long and takes two bytes

print 'write it to file'

with open('binary.bin','wb') as f:

for s in ss:

n=int(s,2)

print n

s=unichr(n)

f.write(s)

print 'read it to file'

with open('binary.bin','rb') as f:

for s in f.read():

print ord(s)

我正在用部分在第二个读取一个字节,但这实际上是不正确的。因为字符串10010101010占用两个字节。在

所以,当我从文件中读取这些字节时,我应该一次读取多少字节?在

#include #include #include #include #include #include typedef struct { int weight; int parent,lchild,rchild; }HTNode,* HuffmanTree;//哈夫曼结构 typedef char **HuffmanCode;//哈夫曼编码 HuffmanTree HT; HuffmanCode HC; int *w,i=0,j=0,n=0,number=0; char *z; void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)//W存放N个字符的权值,构造哈夫曼树HT,并求出N个字符的哈夫曼编码HC { int m,i,s1,s2,start; int c,f; HuffmanTree p; char *cd; if(n<=1) return; m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(p=HT+1,i=1;iweight=*w; p->parent=0; p->lchild=0; p->rchild=0; } for(;iparent=0; for(i=n+1;i<=m;++i)//建树 { j=1; p=HT; while((j<=i-1)&&(p[j].parent!=0))//未建结点个数 j++; s1=j; while(j<=i-1) { if(p[j].parent==0&&p[j].weight<p[s1].weight)//找出最小值s1 s1=j; j++; } p[s1].parent=i; j=1; p=HT; while(j<=i-1&&p[j].parent!=0)//剩余未建结点个数 j++; s2=j; while(j<=i-1) { if(p[j].parent==0&&p[j].weights2) { j=s1; s1=s2; s2=j; } HT[s1].parent=HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //从叶子到根逆向求每个字符的哈夫曼编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); cd=(char*)malloc(n*sizeof(char)); cd[n-1]='\0'; //编码结束符 for(i=1;i<=n;i++)//逐个字符求哈夫曼编码 { start=n-1;//编码结束位置 for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)//从叶子逆向求编码 if(HT[f].lchild==c)//左0右1编码 cd[--start]='0'; else cd[--start]='1'; HC[i]=(char*)malloc((n-start)*sizeof(char)); strcpy(HC[i],&cd[start]); //复制串 } free(cd); } void Initialization()//初使化,从终端读入字符集大小n,以及n个字符和n个权值,建树,并存入文件中 { int num; int quan; cout<>num; n=num; w=(int*)malloc(n*sizeof(int));//存放权 z=(char*)malloc(n*sizeof(char));//存放字符 cout<<"请依次输入"<<n<<"个字符"<<endl; char cs[2]; for(i=0;i<n;i++)//存放字符 { cout<<"第"<<i+1<>cs; *(z+i)=*cs; } cout<<endl<<"请依次输入"<<n<<"个权值"<<endl; for(i=0;i<=n-1;i++)//存放权 { cout<<"第"<<i+1<>quan; *(w+i)=quan; } cout<<"字母表为"; for(i=0;i<=n-1;i++) { cout<<setw(3)<<*(z+i); } cout<<endl; cout<<"权值表为"; for(i=0;i<=n-1;i++) { cout<<setw(3)<<*(w+i); } HuffmanCoding(HT,HC,w,n);//建树,编码 cout<<endl<<"各字符对应的编码为:"<<endl; for(i=1;i<=n;i++) { cout<<*(z+i-1)<<"............................"; cout<<HC[i]<<endl; } //存入文件htmTree中 FILE *htmTree; char rt[]={' ','\0'}; if((htmTree=fopen("htmTree.txt","w"))==NULL) { cout<<"can not open file"<<endl; return; } fputs(z,htmTree); for(i=0;i<n+1;i++) { fprintf(htmTree,"%5d",*(w+i)); fputs(rt,htmTree); } for(i=1;i<=n;i++) { fputs(HC[i],htmTree); fputs(rt,htmTree); } fclose(htmTree); } void InputMessage()//输入要编译的报文,并将其存入文件tobetran中 { FILE *tobetran; char mess[40]; if((tobetran=fopen("tobetran.txt","w"))==NULL) { cout<<"不能打开文件"<<endl; return; } cout<<"请输入想要编码"<<endl; gets(mess); fputs(mess,tobetran); fclose(tobetran); } void Coding()//读取tobetran中的报文,并编码后存入文件codefile中 { FILE *tobetran,*codefile; if((tobetran=fopen("tobetran.txt","rb"))==NULL) cout<<"不能打开文件"<<endl; if((codefile=fopen("codefile.txt","wb"))==NULL) cout<<"不能打开文件"<<endl; char *tran;//中间变量 tran=(char*)malloc(100*sizeof(char)); int i=1; while(i==1) { if(fgets(tran,100,tobetran)==NULL) { cout<<"不能打开文件"<<endl; break; }//将tobetran中读取的字符存入tran中 for(i=0;*(tran+i)!='\0';i++) { for(j=0;j<=n;j++) { if(*(z+j-1)==*(tran+i))//找到第i个字符对应在Z中的位置 fputs(HC[j],codefile);//编码并存入codefile中 } } } fclose(tobetran); fclose(codefile); free(tran); } void Decoding()//利用已建好的哈夫曼树将codefile中的代码进行译码,并将结果存入文件txtfile中 { FILE *codef,*txtfile; if((txtfile=fopen("Textfile.txt","w"))==NULL) cout<<"不能打开文件"<<endl; if ((codef=fopen("codefile.txt","r"))==NULL) cout<<"不能打开文件"<<endl; char w[1000],v[1000]; int j=0,i=0,m=0; fgets(w,2000,codef);//将编码存入W中 m=2*n-1; for(i=0;*(w+i-1)!='\0';i++) { if(HT[m].lchild==0&&HT[m].rchild==0) //,无孩子,是叶子结点 { *(v+j)=*(z+m-1);//找到字符 j++; m=2*n-1; i--; } else if(*(w+i)=='0') m=HT[m].lchild;//有孩子 else if(*(w+i)=='1') m=HT[m].rchild; } *(v+j+1)='\0'; fputs(v,txtfile);//将字符存入文件夹中 fclose(txtfile); fclose(codef); } void Pcode()//将codefile以紧凑可式显式在终端上,每行50个代码,结果存入 CodePrin中 { FILE * CodePrin,* codefile; if((CodePrin=fopen("CodePrin.txt","w"))==NULL) { cout<<"不能打开文件"<<endl; return; } if((codefile=fopen("codefile.txt","r"))==NULL) { cout<<"不能打开文件"<<endl; return; } char *q; //char *y='\r'; q=(char*)malloc(51*sizeof(char));//存50个字符 do {//将codefile中的每50个字符存入q中 if(fgets(q,51,codefile)==NULL) { cout<<"不能读取文件"<<endl; break; } fputs(q,CodePrin); //fputs(y,CodePrin); puts(q); }while(strlen(q)==50); free(q); fclose(CodePrin); fclose(codefile); } void Print(HuffmanTree p,HuffmanTree HT)//打印哈夫曼树,并将其存入TreePrint中 { if(p!=HT) { FILE * TreePrint; if((TreePrint=fopen("TreePrint.txt","a"))==NULL) { cout<<"创建文件失败"<rchild,HT); cout<<setw(6*number)<weight<weight); Print(HT+p->lchild,HT); number--; fclose(TreePrint); } } void main() { char a; while(a!='Q') { cout<<"请选择要执行的命令:"<<endl; cout<<"I 初使化,建立哈夫曼树; S 输入翻译的报文; E 对报文编码;"<<endl<<" D 对编码进行译码; P 打印代码文件; T 打印哈夫曼树; Q 退出"<>a; switch(a) { case'I': Initialization();//初使化,建立哈夫曼树 break; case'S': InputMessage();//输入要翻译的报文 break; case'E': Coding();//读取报文并编码 break; case'D': Decoding();//将代码进行译码 break; case'P': cout<<"打印编码"<<endl; Pcode(); break; case'T': cout<<"打印哈夫曼树"<<endl; Print(HT+2*n-1,HT);//打印哈夫曼树 cout<<"原文,编码和译码结果可在文件中查找。"; break; } } free(z); free(w); free(HT); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值