檔案的壓縮與解壓

2022-05-16 17:05:09 字數 4447 閱讀 1768

#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...