アルファベットとその出現確率を与え、入力された文字列を算術符号化するプログラムを書いたのですが、小数が希望の桁数まで計算されていないのか上手くいきません。double型で計算しているのに結果の桁数がとても小さいです。どうかご教授をお願いいたします。
分割された区間の中央を代表値とし、その二進表記の小数点下l桁を符号語としています。
C
1#include <stdio.h> 2#include <string.h> 3#include <math.h> 4 5struct SET{ 6 char s; 7 double p; 8};//アルファベットとその確率を格納 9 10 11void encode(int asize,struct SET *S,char *s){//符号化のための関数 12 double range[asize],buf,m; 13 int l; 14 range[0]=0; 15 16 for(int i=1;i<=asize;i++){ 17 range[i]=range[i-1]+S[i-1].p; 18 }//区間[0,1)の分割 19 20 for(int i=0;i<strlen(s);i++){ 21 for(int j=0;j<asize;j++){ 22 if(S[j].s==s[i]){ 23 printf("s[%d]=%s\n",i,&S[j].s); 24 range[0]=range[j]; 25 buf=range[j+1]; 26 for(int k=1;k<=asize;k++){ 27 range[k]=range[k-1]+S[k-1].p*(buf-range[0]); 28 } 29 printf("range:[%lf,%lf)\n",range[0],range[asize]);//最終的な区間を表示 30 } 31 } 32 } 33 34 m=(range[0]+range[asize])/2; 35 36 printf("range:[%lf,%lf)\n",range[0],range[asize]); 37 printf("encoded:"); 38 l=ceil(-log2l(m))+1;//符号語の長さを決定するl 39 for(int i=1;i<=l;i++){ 40 printf("%d",(int)floor(m*2));//符号語を表示 41 m=m*2-floor(m*2); 42 } 43 printf("\n"); 44 45} 46 47int main (){ 48 int asize,i; 49 char s[256];//文字列 50 struct SET S[256]; 51//アルファベットと出現確率を入力 52 printf("alphabet size:"); 53 scanf("%d",&asize); 54 55 for(i=0;i<asize;i++){ 56 57 printf("symbol_%d:",i); 58 scanf("%s",&S[i].s); 59 60 printf("p_%d:",i); 61 scanf("%lf",&S[i].p); 62 } 63 64 printf("symbols:"); 65 scanf("%s",s);//文字列を入力 66 67 encode(asize,S,s); 68 69 70 return 0; 71 72} 73
例えば
a
0.1
b
0.2
c
0.4
d
0.2
を与えると
記号列aadbbdcccc
符号語は
000010001100001010001
のはずが先頭6桁しか表示されません、区間の両端の値も桁数が小さいです。
符号化対象の文字列データは何ですか?(質問文中から欠落しているように見受けられます)
回答2件
あなたの回答
tips
プレビュー