『壹』 如何用c語言實現數據壓縮
首先選擇一個壓縮演算法
然後按照演算法實現壓縮代碼,調用介面就可以
常見的 可以使用哈夫曼編碼壓縮,或者使用開源的壓縮代碼,比如lzo, gzip, lzma等等。
『貳』 用C語言算術編碼的數據壓縮
哈夫曼編碼
『叄』 在壓縮文件中,已得知01二進制編碼順序怎麼用C語言寫入二進制文件中實現壓縮、
我先講解下壓縮的原理,你懂了就知道怎麼去實現了。 壓縮的原理就是用較短的子串來表示較長的子串。通俗的說比如我發明一種演算法將「」可以簡化成「50,1」,表示「50個1」,本來50個字的就可以用「50,1」這4個字表示,解壓的時候再把「50,1」還原成「」
所以一個bmp圖片可以壓縮的很厲害,因為有很多重復性的信息,而jpeg在壓縮也壓縮不了多少,因為沒有太多重復性信息。你把一幅全黑的bmp圖片可以壓縮的很小,而一個色彩斑斕的bmp圖片則相對來說壓縮處來的文件就會比較大。
『肆』 求:C語言的遊程編碼,要求將大量的二進制的數據壓縮
遊程數就多,變化少的部分遊程數就少,原始柵格類型越簡單,壓縮效率就越高
『伍』 huffman編碼壓縮文件 c語言
解決這個問題就是了解什麼是huffman編碼,看下書就可以了同學。。。。
『陸』 求用C語言寫的圖像壓縮(JPEG)編碼中zigzag編程部分
你說的是這段?
還是包括後面的huffman編碼部分
static UChar zigzag[64]={ 0, 1, 5, 6,14,15,27,28,
2, 4, 7,13,16,26,29,42,
3, 8,12,17,25,30,41,43,
9,11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63 };
//zigzag reorder
for (i=0;i<=63;i++) DU[zigzag[i]]=DU_DCT[i];
『柒』 有懂行程編碼的么用C語言實現字元的壓縮。求大神幫助阿!
#include<stdio.h>
#include<string.h>
void main()
{
char s[51];
int i=0,j=1;
printf("請輸入一個長度不超過五十的字元串(否則會越界出錯):\n");
scanf("%s",s);
if(strlen(s)>50){
printf("輸入不合要求!");
return;
}
while(i<strlen(s))
{
//j用於統計重復的字母個數
if(s[i]==s[i+1])
j++;
else{
printf("%d%c",j,s[i]);
j=1;//j重新計數
}
i++;
}
printf("\n");
}
『捌』 急求lzw演算法的英文文本壓縮C語言源代碼!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>//用來計算壓縮的時間
using namespace std;
//定義常數
const int MAX = 1000003;//最大code數,是一個素數,求模是速度比較快
const int ascii = 256; //ascii代碼的數量
const int ByteSize = 8; //8個位元組
struct Element//hash表中的元素
{
int key;
int code;
Element *next;
}*table[MAX];//hash表
int hashfunction(int key)//hash函數
{
return key%MAX;
}
void hashinit(void)//hash表初始化
{
memset(table,0,sizeof(table));
}
void hashinsert(Element element)//hash表的插入
{
int k = hashfunction(element.key);
if(table[k]!=NULL)
{
Element *e=table[k];
while(e->next!=NULL)
{
e=e->next;
}
e->next=new Element;
e=e->next;
e->key = element.key;
e->code = element.code;
e->next = NULL;
}
else
{
table[k]=new Element;
table[k]->key = element.key;
table[k]->code = element.code;
table[k]->next = NULL;
}
}
bool hashfind(int key,Element &element)//hash表的查找
{
int k = hashfunction(key);
if(table[k]!=NULL)
{
Element *e=table[k];
while(e!=NULL)
{
if(e->key == key)
{
element.key = e->key;
element.code = e->code;
return true;
}
e=e->next;
}
return false;
}
else
{
return false;
}
}
void compress(void)//壓縮程序
{
//打開一個流供寫入
FILE *fp;
fp = fopen("result.dat", "wb");
Element element;
int used;
char c;
int pcode, k;
for(int i=0;i<ascii;i++)
{
element.key = i;
element.code = i;
hashinsert(element);
}
used = ascii;
c = getchar();
pcode = c;
while((c = getchar()) != EOF)
{
k = (pcode << ByteSize) + c;
if(hashfind(k, element))
pcode = element.code;
else
{
//cout<<pcode<<' ';
fwrite(&pcode, sizeof(pcode), 1, fp);
element.code = used++;
element.key = (pcode << ByteSize) | c;
hashinsert(element);
pcode = c;
}
}
//cout<<pcode<<endl;
fwrite(&pcode, sizeof(pcode), 1, fp);
}
int main(void)
{
int t1,t2;
//欲壓縮的文本文件
//freopen("input.txt","r",stdin);
freopen("book5.txt","r",stdin);
t1=time(NULL);
hashinit();
compress();
t2=time(NULL);
cout<<"Compress complete! See result.dat."<<endl;
cout<<endl<<"Total use "<<t2-t1<<" seconds."<<endl;
『玖』 c語言哈弗曼編碼 壓縮程序怎麼寫啊
哈弗曼編碼涵義是將一竄數字或者字母按哈弗曼數的形式編碼,並使得這竄字元中的每個數字或者字母都能被唯一的「0,1」序列來編碼,而且沒有相同的前綴,這是一種非等長的編碼方式。
如果你覺得這樣解釋很難聽懂的話就舉個例子:
如果用計算機發信息,只能用0和1,但是每個字母的使用頻度又不一樣,比如a,i,o,e等這些字母使用的就多些,而z,v這樣的字母使用的就少一些,如果所有字母都用等長的0,1序列來編碼的話會造成浪費,那麼我們就把常用的字母用少點的0,1,進行編碼(比如用兩個或三個),不常用的再用多點0,1編碼,但是還不能造成油相同前綴的情況,這會使計算機無法識別,比如E用010,z用01001,計算機就只能識別出前面三個是E,而後面就拋棄或者識別出別的字母。哈弗曼編碼就是出於這樣的條件下產生的。也許這樣的形容還是很抽象,那麼再具體點。
加入a,b,c,d,e使用的頻度分別是10,7,5,5,3
那麼就可以構造哈弗曼數:
從樹頂到樹根,假如左邊是0,右邊是1,那麼就能得到他們的哈弗曼編碼(就是從上到下,到達他們字母經過的路徑),分別是:
a:00;b:11;c:10;d:011;e:010;
你可以發現他們全部沒有相同的前綴。
具體的編碼方式我可以大致的跟你說下,因為我還在上班所以無法使用自己的電腦進行編譯,怕寫的有錯誤,
你拿到一個待編碼的數據肯定有標識符(即上面的a,b,c),還有所帶的權值(即3,5,5等)
你需要用哈弗曼演算法構造出哈弗曼編碼,即每次取最小的兩個數當作葉子,來生成樹根(樹根的值等於他們的和),整數據就少了一個,直到最後兩個數相加的值作為最終的樹根。
然後從上往下,左邊為0右邊為1,到達每個樹葉(即是標識符的位置),那麼路徑的編碼就是他的哈弗曼編碼。
以上是演算法,建議你可以用一個結構體(帶標識符,權值,哈弗曼編碼(編碼暫時為空)),用一個vector(C++裡面的數據類型)裝載他們並按照權值大小進行排序,然後通過哈弗曼演算法(另用一個函數來計算)創建一個哈弗曼數,並計算出它的哈弗曼編碼並寫到結構體中,這樣就把字元進行了哈弗曼壓縮。
這就是整個過程
『拾』 如何用C語言編寫Huffman編碼壓縮文件的程序
我的的網路博客中有,名字李少龍感謝你的博客!你找一下huffman編碼就有了!
/* 程序的設計的主要思路:把哈弗曼數組的下標和字元的ASCII碼以及存儲哈
弗曼編碼的向量的下標對應起來,這樣可以使得編碼和設計思路比較容易*/
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#define SIZE 514
using namespace std;
struct Huffman_Node {
Huffman_Node(int f=0, int l=0, int r=0, int p=0):freq_(f), lc_(l),rc_(r){}
long freq_;
int lc_;
int rc_;
};
Huffman_Node huff[514];//哈弗曼樹結構數組
char source_file1[30],source_file2[30],source_file3[30];//三個文件名
vector<char> huff_code[257];//儲存哈弗曼碼
stack <char> board;//在解壓的時候用到棧
queue <char> queueing;//在壓縮的時候用的隊列
void statistic(void);//頻率的統計
void create_Huffman(void);//建立哈弗曼數
void Select(int start,int end,int &s1,int &s2);//找出哈弗曼數組中頻率最小的兩個
bool harh(int root);//判斷右子是否為空
bool halh(int root);//判斷左子是否為空
void pre_orderi(int r, vector<char> temp);//前序遍歷哈弗曼樹
int calculate(void);//把二進制轉換成十進制
void change(int num);//把十進制轉換成二進制
void decompression(void);//解壓
void coding(void);//壓縮
int main()
{
int i;
vector<char> temp;
string file1;
system("COLOR F3");//改變窗口的顏色
statistic();//統計文件裡面字元的頻率
create_Huffman();//建立哈弗曼樹
for (i=0;i<=513;i++) {//把哈弗曼樹列印出來
if (huff[i].freq_!=0)
cout<<i<<'\t'<<huff[i].freq_<<'\t'<<huff[i].lc_<<'\t'<<huff[i].rc_<<endl;
}
pre_orderi(513, temp);//前序遍歷哈弗曼樹
for (i=0;i<=256;i++) {
if (huff_code[i].size()>0) {
cout<<i<<'\t';
for (int j=0;j<huff_code[i].size();j++) {
cout<<huff_code[i][j];
}
cout<<endl;
}
}
coding();//壓縮
decompression();//減壓
return 0;
}
//判斷節點的右子是否為空
bool harh(int root)
{
if (huff[root].rc_==0)
return false;
else
return true;
}
//判斷節點的左子是否為空
bool halh(int root)
{
if (huff[root].lc_==0) {
return false;
}
else
return true;
}
//前序遍歷哈弗曼樹,在建立哈弗曼樹和解壓文件時用到
void pre_orderi(int r, vector<char> temp)
{
if (r==0)
return;
if (!halh(r)&&!harh(r)) {
huff_code[r]=temp;
return;
}
temp.push_back('0');
pre_orderi(huff[r].lc_, temp);
temp.pop_back();
temp.push_back('1');
pre_orderi(huff[r].rc_, temp);
}
//把二進制轉換成十進制
int calculate(void)
{
int sum=0;
int num;
while (!queueing.empty()) {
if (queueing.front()=='0') {
num=0;
}
else
num=1;
sum=sum*2+num;
queueing.pop();
}
return sum;
}
//把十進制轉換成二進制
void change(int num)
{
for (int i=0;i<=7;i++) {
if (num%2==0)
board.push('0');
else
board.push('1');
num/=2;
}
}
//解壓文件
void decompression(void)
{
int i=0,j=0;
bool end=true;
int root=513;//根節點
int Binary;
ifstream infile;
ofstream outfile;
cout<<'\t\t'<<"請輸入解壓存儲文件名,格式為<XXX.txt>:";
cin>>source_file3;
infile.open(source_file2,ios::binary);
outfile.open(source_file3,ios::binary);
while (end) {//判斷文件是否結束
Binary=infile.get();
//從文件中讀取一個字元並轉換成整形
if (Binary<0) {
Binary+=256;
}
change(Binary);
//沿著哈弗曼編碼來遍歷哈弗曼樹
while (!board.empty()) {
//若遇到葉節點則
if (!halh(root)&&!harh(root)) {
if(root==256){//遇到文件結束符則停止
while (!board.empty()) {//把棧清空
board.pop();
}
infile.close();
outfile.close();
return;
}
else{//把葉節點的下標轉換成字元
outfile.put(root);
root=513;//再把根節點置為樹的根節點
}
}
if (board.top()=='0') {
root=huff[root].lc_;
}
else if (board.top()=='1') {
root=huff[root].rc_;
}
board.pop();
}
}
}
//壓縮文件
void coding(void)
{
int i=0,j=0;
int Binary;
ifstream infile;
ofstream outfile;
cout<<"請輸入壓縮碼存儲文件名,格式為<XXX.txt>:";
cin>>source_file2;
infile.open(source_file1,ios::binary);
outfile.open(source_file2,ios::binary);
Binary=infile.get();
while (Binary!=EOF) {//遇到文件結束符
for (i=0;i<huff_code[Binary].size();i++) {
queueing.push(huff_code[Binary][i]);
if (queueing.size()>=8) {
j=calculate();
outfile.put(j);
}
}
Binary=infile.get();
}
//添加文件結束符
for (i=0;i<huff_code[256].size();i++) {
queueing.push(huff_code[256][i]);
if (queueing.size()>=8) {
j=calculate();
outfile.put(j);
}
}
//若隊列的大小小於8的話則向隊列添加0
while (queueing.size()<8) {
queueing.push('0');
}
j=calculate();
outfile.put(j);
outfile.close();
infile.close();
}
//統計文件中字元的頻率
void statistic(void)
{
int Binary;
cout<<'\t'<<'\t'<<"請輸入要壓縮的文件名:";
cin>>source_file1;
ifstream infile(source_file1, ios::binary);
while ((Binary=infile.get())!=EOF) {
if (Binary<0)
Binary+=256;
huff[Binary].freq_++;
}
huff[256].freq_=1;
infile.close();
}
//尋找數組中兩個頻率最小的字元的下標並返回
void Select(int num[],int start,int end,int &s1,int &s2)
{
int Miner=0x7FFFFFFF;// 初始化為最大的正整數
int Minest=0x7FFFFFFF;
int x_Miner=0;
int x_Minest=0;
for(int i=start;i<=end;i++)
{
if(num[i]<Minest&&num[i]>0)
{
x_Miner=x_Minest;
Miner=Minest;
Minest=num[i];
x_Minest=i;
}
else if(num[i]<Miner&&num[i]>0){
Miner=num[i];
x_Miner=i;
}
}
num[end+1]=Miner+Minest;
num[x_Miner]=0;
num[x_Minest]=0;
s1=x_Minest;
s2=x_Miner;
}
//生成HUFFMAN樹
void create_Huffman(void)
{
int num[514]={0};
int i;
int s1(0),s2(0);
const int n=257;
for (i=0;i<=256;i++) {
num[i]=huff[i].freq_;
}
//建立哈弗曼樹
for (i=n;i<=513;i++, s1=0, s2=0) {
Select(num,0,i-1,s1,s2);//從0節點到i-1節點找兩個最小數,返回
if (s1==0||s2==0) {
break;
}
huff[i].freq_=huff[s1].freq_+huff[s2].freq_;
huff[i].lc_=s1;
huff[i].rc_=s2;
}
//把哈弗曼數組的左後一個節點作為哈弗曼樹的根節點
huff[513].freq_=huff[--i].freq_;
huff[513].lc_=huff[i].lc_;
huff[513].rc_=huff[i].rc_;
}