‘壹’ 如何用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_;
}