huffman压缩存储和解压缩源代码(精品文档)
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
fst.open(filename, ifstream::in|ifstream::binary); wfile(fst, pssfile, Bytecode); fst.close(); pssfile.close(); system("pause"); }
void HuffmanCoding(array<huffman, m> &HT, array<string, n> &code, array<double, n> freq) { int j; unsigned char cj = 0; for (j = 0; j < n; ++j) { HT[cj].freq = freq[cj]; HT[cj].lchild = 0; HT[cj].rchild = 0; HT[cj].parent = 0; ++cj; } int i,s1, s2; for (i= n ; i <m; ++i) { myselect(HT, i, s1, s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lchild = s1; HT[i].rchild = s2; HT[i].freq = HT[s1].freq + HT[s2].freq; } for (i = 0; i < n; ++i) { string cd(n-1, '0'); int start = n-1; int k, f; for (k = i, f = HT[i].parent; f != 0; k = f, f = HT[f].parent) if (HT[f].lchild == k) cd[--start] = '0'; else cd[--start] = '1'; string cds(cd.substr(start, (n-1) - start)); code[i] = cds; }
n> freq);
double freq;
int parent;
int lchild;
int rchild;
public:
huffman() {
freq = 0;
parent = 0;
lchild = 0;
rchild = 0;
}
huffman(double
sfreq,int
sparent,int
slchild,int
cout << "请输入要压缩的文件名:" << endl; getline(cin, filename); cout << "请输入解压缩文件的文件名(无需后缀):" << endl; getline(cin, pssname); pssname = pssname + ".bin";
ifstream fst(filename,ifstream::binary); if (!fst) {
cout << "文件打开失败" << endl; system("pause"); exit(0); } createfreq(fst,freq,sumchar); fst.close();
HuffmanCoding(HT,code,freq); //编码
//for (int p = 0; p < n; ++p)
nextpen = 255;
nextpen = nextpen >> (8 - lenpen);//这个相当于 nextpen 的长度
nextpen = nextpen & tempchar;
nextpen = nextpen << (8 - lenpen);
tempchar = tempchar >> lenpen;
// cout << code[p] <<"\t"<< p <<endl;
stoByte(code, Bytecode);
//将字符串码转化为字节码
ofstream pssfile(pssname, ofstream::binary |ofstream::out); if (!pssfile) {
cout << "文件打开失败" << endl; system("pause"); exit(0); } pssfile.write((char*)(&sumchar),sizeof(double)); dictofile(pssfile,Bytecode);
}
void myselect(array<huffman, m> &HT, int end, int& s1, int& s2) { int i; double min1=1, min2=1; for (i = 0; i < end; ++i) { if (HT[i].parent == 0) { if (HT[i].freq < min1) { s2 = s1; s1 = i; min2 = min1; min1 = HT[i].freq;
}
++cj; } }
void wfile(ifstream& fst, ofstream &pssfile, array<string, n> Bytecode) { char tempc; unsigned char bitlen; string temps; unsigned char pen = 0, lenpen = 0, nextpen = 0, tempchar = 0, lencode = 0; unsigned char i;
} else if (HT[i].freq < min2) {
s2 = i; min2 = HT[i].freq; } } } }
void stoByte(array<string, n> code, array<string, n> &Bytecode) { int j; unsigned char cj=0; string curByte; unsigned char lencurByte, index = 0, pen=0, temp; string curstr;
压缩部分 C++代码 #include<iostream> #include<fstream> #include <string> #include <array> #include <sstream> #include <vector> #include <cstdlib> #include <iomanip> #define n 256 #define m 511 using namespace std; unsigned char cst = 8;
freq); void myselect(array<huffman, m> &HT, int end,int& s1, int& s2); void stoByte(array<string, n> code, array<string, n> &Bytecode); void wfile(ifstream& fst, ofstream &pssfile, array<string, n> Bytecode); void createfreq(ifstream& fst, array<double, n> &freq,double &sumchar); void dictofile(ofstream &pssfile,array<string, n> Bytecode);
for (j = 0; j < n; ++j) { index = 0; curByte = code[cj]; lencurByte = curByte.length(); Bytecode[cj] = Bytecode[cj] + static_cast<char>(lencurByte);
度
//在字典里加入位的长
i = 1;
while (lencode--) { if (bitlen + lenpen < cst) {
//如果这一次读入的编码还不够写满
tempchar = temps[i];
tempchar = tempchar >> lenpen; //移位后给 pen
pen = pen | tempchar; lenpen += bitlen; //pen 的长度发生变化
while (fst.get(tempc)) {
temps = Bytecode[static_cast<unsigned char>(]; //bitlen 存储的是编码有多少位
lencode = temps.length() - 1; //lencode 存储的是编码以 字节形式有多少字节
while (lencurByte > index) { if (lencurByte - index < cst) { curstr = curByte.substr(index, lencurByte - index); string t(cst - (lencurByte - index),'0'); curstr = curstr + t; index = lencurByte;//保证 curstr 始终有 8 位长度 } else { curstr = curByte.substr(index, cst); index += cst; } for (int i = 0; i < 8; i++) { temp = curstr[i] - 48; temp = temp << (7 - i); pen = pen | temp; } Bytecode[cj] = Bytecode[cj] + static_cast<char>(pen); pen = 0;
srchild):freq(sfreq),parent(sparent),lchild(slchild),rchild(srchild){}
};
int main() { void HuffmanCoding(array<huffman, m> &HT, array<string, n> &code, array<double, n>
pen = pen | tempchar;
pssfile.put(pen);
pen = nextpen;
bitlen -= sb; //bitlen 减去这次写入 pen 和 nextpen 的值
lenpen = sb - (8 - lenpen); //当前 len 改成 nextpen 的长度
++i;
}
}
}
if (lenpen) pssfile.put(pen);
}
void createfreq(ifstream& fst,array<double,n> &freq,double &sumchar) { char tempc; while (fst.read((char *)(&tempc),sizeof(tempc)) ){ ++sumchar; ++freq[static_cast<unsigned char>(tempc)]; } int j; unsigned char cj = 0; for (j = 0; j < n; j++) { freq[cj] = freq[cj] / sumchar; cj++; }
class huffman {
friend void myselect(array<huffman, m> &HT, int end, int& s1, int& s2);
friend void HuffmanCoding(array<huffman, m> &HT, array<string, n> &code, array<double,
bitlen = 0;
//还剩没写入的位数发生变化
break;
}
else {
unsigned char sb = static_cast<unsigned char>(min(8,
static_cast<int>(bitlen))); //可能读入的一个字节够一个 pen 但是不足 8 位
tempchar = temps[i];
string filename; string pssname; array<string, n> code; array<string, n> Bytecode; array<huffman, m> HT; array<double, n> freq{ 0 }; double sumchar = 0;