#include #include#include
#include
struct
head
header[
512],tmp;
/*壓縮
*/void
compress()
printf(
"\t請您輸入壓縮後的檔名:");
gets(outputfile);
ofp=fopen(outputfile,"wb"
);
if(ofp==null)
flength=0
;
while(!feof(ifp))
flength--;
length1=flength; //
原檔案長度用作求壓縮率的分母
header[c].count--;
for(i=0; i<512; i++)
for(i=0; i<256; i++) //
根據頻率(權值)大小,對結點進行排序,選擇較小的結點進樹}}
for(i=0; i<256; i++) if(header[i].count==0) break
; n=i; //
外部葉子結點數為n個時,內部結點數為n-1,整個哈夫曼樹的需要的結點數為2*n-1.
m=2*n-1
;
for(i=n; i//
構建哈夫曼樹
}header[i].count=header[pt1].count;
header[pt1].parent=i; //
依據parent域值(結點層數)確定樹中結點之間的關係
header[i].lch=pt1; //
計算左分支權值大小
min1=999999999
;
for(j=0; j)
}header[i].count+=header[pt1].count;
header[i].rch=pt1; //
計算右分支權值大小
header[pt1].parent=i;
}for(i=0; i//
哈夫曼無重複字首編碼
else
//置右分支編碼1}}
fseek(ifp,
0,seek_set); //
從檔案開始位置向前移動0位元組,即定位到檔案開始位置
fwrite(&flength,sizeof(int),1
,ofp);
/*用來將資料寫入檔案流中,引數flength指向欲寫入的資料位址,
總共寫入的字元數以引數size*int來決定,返回實際寫入的int數目1
*/fseek(ofp,
8,seek_set);
buf[
0]=0; //
定義緩衝區,它的二進位制表示00000000
f=0; pt1=8
;
/*假設原檔案第乙個字元是"a",8位2進製為01000001,編碼後為0110識別編碼第乙個'0',
那麼我們就可以將其左移一位,看起來沒什麼變化。下乙個是'1',應該|1,結果00000001
同理4位都做完,應該是00000110,由於位元組中的8位並沒有全部用完,我們應該繼續讀下乙個字元,
根據編碼表繼續拼完剩下的4位,如果字元的編碼不足4位,還要繼續讀乙個字元,
如果字元編碼超過4位,那麼我們將把剩下的位資訊拼接到乙個新的位元組裡
*/while(!feof(ifp))
strcat(buf,header[i].bits);
j=strlen(buf);
c=0;
while(j>=8) //
對哈夫曼編碼位操作進行壓縮儲存
fwrite(&c,1,1
,ofp);
pt1++; //
統計壓縮後檔案的長度
strcpy(buf,buf+8); //
乙個位元組乙個位元組拼接
j=strlen(buf);
}if(f==flength) break
; }
if(j>0) //
對哈夫曼編碼位操作進行壓縮儲存
fwrite(&c,1,1
,ofp);
pt1++;
}fseek(ofp,
4,seek_set);
fwrite(&pt1,sizeof(long),1
,ofp);
fseek(ofp,pt1,seek_set);
fwrite(&n,sizeof(long),1
,ofp);
for(i=0; i)
while(header[i].bits[0]!=0
)
strcpy(header[i].bits,header[i].bits+8); //
把字元的編碼按原先儲存順序連線
fwrite(&c,1,1
,ofp);}}
length2=pt1--;
div=((double)length1-(double)length2)/(double)length1; //
計算檔案的壓縮率
fclose(ifp);
fclose(ofp);
printf(
"\n\t壓縮檔案成功!\n");
printf(
"\t壓縮率為 %f%%\n\n
",div*100
);
return;}
/*解壓縮
*/void
uncompress()
printf(
"\t請您輸入解壓縮後的檔名:");
gets(outputfile);
ofp=fopen(outputfile,"wb"
);
if(ofp==null)
fread(&flength,sizeof(long),1,ifp); //
讀取原檔案長度,對檔案進行定位
fread(&f,sizeof(long),1
,ifp);
fseek(ifp,f,seek_set);
fread(&n,sizeof(long),1
,ifp);
for(i=0; i)
strcat(header[i].bits,buf);
}header[i].bits[p]=0
; }
for(i=0; i//
根據哈夫曼編碼的長短,對結點進行排序}}
p=strlen(header[n-1
].bits);
fseek(ifp,
8,seek_set);
m=0; bx[
0]=0
;
while(1) //
通過哈夫曼編碼的長短,依次解碼,從原來的位儲存還原到位元組儲存
strcat(bx,buf);
}for(i=0; i)
strcpy(bx,bx+header[i].count); /*
從壓縮檔案中的按位儲存還原到按位元組儲存字元,
字元位置不改變
*/c=header[i].b;
fwrite(&c,1,1
,ofp);
m++; //
統計解壓縮後檔案的長度
if(m==flength) break; //
flength是原檔案長度
} fclose(ifp);
fclose(ofp);
printf(
"\n\t解壓縮檔案成功!\n");
if(m==flength) //
對解壓縮後檔案和原檔案相同性比較進行判斷(根據檔案大小)
printf("
\t解壓縮檔案與原檔案相同!\n\n");
else printf("
\t解壓縮檔案與原檔案不同!\n\n");
return;}
/*主函式
*/int
main()
}while(c!='
0' && c!='
1' && c!='2'
);
if(c=='
1') compress(); //
呼叫壓縮子函式
else
if(c=='
2') uncompress(); //
呼叫解壓縮子函式
else
system(
"pause
"); //
任意鍵繼續
system("
cls"); //清屏}
return0;
}
檔案壓縮與解壓
檔案的壓縮 1.讀取檔案的內容 2.統計每個字元出現的次數 int read while read bis.read 1 直至讀到檔案結束 arrays為運算元組的工具類 collections為操作集合工具類 bis.close 3.構建哈弗曼樹,生成哈夫曼編碼 if node.getleftno...
檔案壓縮與解壓
檔案壓縮與解壓思想 1 統計字元出現次數,結合最小堆的性質生成哈夫曼樹 2 對葉節點進行編碼,結點左邊編 0,右邊編1 3 讀取檔案,用哈夫曼編碼代替字元產生新的字元,即壓縮 4 讀取壓縮檔案,進行哈夫曼編碼的解讀產生相應字元,即解壓 例如,對以下資料生成哈夫曼樹,以及產生相應的哈夫曼編碼 自己寫的...
檔案的壓縮與解壓
include include include include struct head header 512 tmp 壓縮 void compress printf t請您輸入壓縮後的檔名 gets outputfile ofp fopen outputfile,wb if ofp null fle...