當前位置:首頁 » 操作系統 » 數據壓縮演算法實現

數據壓縮演算法實現

發布時間: 2022-09-01 12:15:01

壓縮文件如何達到高壓縮率

壓縮文件達到高壓縮率的方法有:

1、首先,我們對我們需要進行壓縮操作的文件擊右鍵,選擇「添加到壓縮文件」。

2、由於我們在進行壓縮文件的時候,如果我們將文件格式選擇為.rar,一般來說這樣壓縮的文件的壓縮比率是較高的。如果我們選擇了.zip文件格式,那麼一般情況下壓縮比率是比較小的,所以我推薦大家還是選擇為.rar的文件格式。

3、接下來,我們需要進行的操作就是,將「創建固實壓縮文件」和「測試壓縮文件」兩個選項勾選,這樣我們下來壓縮的文件就會比較小,大家可以看看自己文件屬性裡面的壓縮比率,如果文件很大的話,會很明顯。希望大家勾選「測試壓縮文件」,因為我們可能會在壓縮文件的過程中遇到某些未知錯誤。

4、接下來,我們就可以點擊「確定」,軟體就會自動進行壓縮操作,然後看看我們的文件的壓縮比率吧。

5、如果我們需要壓縮的文件的體積很大,那麼為了節約時間,一般情況下也是可以將文件格式選擇為.zip,畢竟這樣可以節約很多時間的。

(1)數據壓縮演算法實現擴展閱讀:

常用的圖像壓縮軟體有:

①JPEG Optimizer

JPEG Optimizer是一個可以按照指定的壓縮比壓縮JPEG格式圖片的工具軟體,它使用Magic Compress技術,能對 JPEG圖形文件壓縮50%而不損失畫質,自定壓縮比,能即時顯現壓縮後的圖片,比較差異,效果相當不錯。而所有這一切,只需要通過調整桿進行壓縮比調整即可。

②The JPEG Wizard

The JPEG Wizard可以在不影響圖像質量的情況下對圖片進行最大限度的壓縮,同時支持對圖片的局部壓縮、剪切、旋轉,調整圖片的對比度、亮度和色度。另外,The JPEGWizard還具有較強的批處理功能,避免重復性操作。

③7-Zip

7-Zip是一款號稱有著現今最高壓縮比的壓縮軟體,它不僅支持獨有的7z文件格式,而且還支持各種其他壓縮文件格式,其中包括ZP、RAR、CAB、GZIP、BZP2和TAR。此軟體壓縮的壓縮比要比普通ZIP文件30%~50%。因此,它可以把經 Winzip壓縮的文件再壓縮2%~10%。

Ⅱ 數據無損壓縮技術到底怎麼實現的

無損數據壓縮(Lossless Compression)是指使用壓縮後的數據進行重構(或者叫做還原,解壓縮),重構後的數據與原來的數據完全相同;無損壓縮用於要求重構的信號與原始信號完全一致的場合。也就是說數據經過壓縮後信息不受損失,還能完全恢復到壓縮前的原樣。它和有損數據壓縮相對。這種壓縮通常壓縮比小於有損數據壓縮的壓縮比。
一個很常見的例子是磁碟文件的壓縮。根據目前的技術水平,無損壓縮演算法一般可以把普通文件的數據壓縮到原來的1/2~1/4。一些常用的無損壓縮演算法有霍夫曼(Huffman)演算法和LZW(Lenpel-Ziv & Welch)壓縮演算法。

Ⅲ 利用huffman樹實現文件的壓縮與解壓

這是本人寫的動態哈夫曼壓縮演算法實現,壓縮與解壓縮時,
根據文件內容自動生成哈夫曼樹,並動態調整節點的權重
和樹的形狀。900MHZ的PIII賽揚每秒鍾可以壓縮的好幾MB
的數據,只是壓縮率不高,文本文件的壓縮後容量一般可
以減少25%,比RAR差遠了。

源文件共三個,你在VC6.0中新建一個空的命令行項目,
將它們加進去,編譯完就可以用了。

===========hfm.cpp===================

#include <stdio.h>
#include <string.h>
#include <io.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "Huffman.h"

int wh;
int rh;

bool Write(unsigned char *s,int len){
_write(wh,s,len);
return true;
}

bool OpenFile(char* source,char* target){
int w_flag=_O_WRONLY | _O_CREAT | _O_EXCL | _O_BINARY;
int r_flag=_O_RDONLY | _O_BINARY;

rh=_open(source,r_flag,_S_IREAD | _S_IWRITE);
wh=_open(target,w_flag,_S_IREAD | _S_IWRITE);

if(rh==-1 || wh==-1){
if(rh!=-1){
_close(rh);
printf("\n打開文件:'%s'失敗!",target);
}
if(wh!=-1){
_close(wh);
printf("\n打開文件:'%s'失敗!",source);
}

return false;
}else{
return true;
}
}

void PrintUsage(){
printf("\n以動態哈夫曼演算法壓縮或解壓縮文件。\n\n");
printf("\thfm -?\t\t\t\t顯示幫助信息\n");
printf("\thfm -e -i source -o target\t壓縮文件\n");
printf("\thfm -d -i source -o target\t解壓縮文件\n\n");
}

void main(int argc,char *args[]){
int mode,i,j,K=0;
char src[4096];
char target[4096];
unsigned char buffer[BUFFER_SIZE];
Huffman *h;

mode=0;
for(i=1;i<argc;i++){
if(args[i][0]=='-' || args[i][0]=='/'){
switch(args[i][1]){
case '?':
mode=0;//幫助
break;
case 'e':
case 'E':
mode=1;//壓縮
break;
case 'd':
case 'D':
mode=2;//解壓縮
break;
case 'o':
case 'O':
if(i+1>=argc){
mode=0;
}else{//輸出文件
j=0;
while(args[i+1][j]!='\0' && j<4096){
target[j++]=args[i+1][j];
}
if(j==4096){
mode=0;
}else{
target[j]='\0';
K |= 1;
}
}
break;
case 'i':
case 'I':
if(i+1>=argc){
mode=0;
}else{//輸入文件
j=0;
while(args[i+1][j]!='\0' && j<4096){
src[j++]=args[i+1][j];
}
if(j==4096){
mode=0;
}else{
src[j]='\0';
K |=2;
}
}
break;
}
}
}

if(K!=3)mode=0;

switch(mode){
case 0:
PrintUsage();
return;
case 1://壓縮
if(!OpenFile(src,target))return;
h=new Huffman(&Write,true);
i=BUFFER_SIZE;
while(i==BUFFER_SIZE){
i=_read(rh,buffer,BUFFER_SIZE);
h->Encode(buffer,i);
}
delete h;
_close(rh);
_close(wh);
printf("壓縮完畢!");
break;
case 2://解壓縮
if(!OpenFile(src,target))return;
h=new Huffman(&Write,false);
i=BUFFER_SIZE;
while(i==BUFFER_SIZE){
i=_read(rh,buffer,BUFFER_SIZE);
h->Decode(buffer,i);
}
delete h;
_close(rh);
_close(wh);
printf("解壓縮完畢!");
break;
}

}

=======end of hfm.cpp=======================

=======Huffman.cpp=============================
// Huffman.cpp: implementation of the Huffman class.
//
//////////////////////////////////////////////////////////////////////

#include "Huffman.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Huffman::Huffman(Output *output,bool mode)
{
Hbtree *tmp;
int i;

this->mode=mode;

//設置輸出函數,當緩沖區滿時,將調用該函數輸出
this->output=output;

//初始化列表
for(i=0;i<LIST_LENGTH;i++)this->list[i]=NULL;

//初始化哈夫曼樹
this->root=this->NewNode(NOT_CHAR,LEFT,NULL);
this->current=this->root;
tmp=this->NewNode(CODE_ESCAPE,RIGHT,root);
tmp->count=1;
tmp=this->NewNode(CODE_FINISH,LEFT,root);
tmp->count=0;
root->count=root->child[LEFT]->count+root->child[RIGHT]->count;

//設置緩沖區指針
this->char_top=BOTTOM_BIT;
this->bit_top=TOP_BIT;
this->buffer[0]=0;

//重構哈夫曼樹的最大計數值
this->max_count=MAX_COUNT;
this->shrink_factor=SHRINK_FACTOR;
this->finished=false;
}

Huffman::~Huffman()
{
if(this->mode==true){//如果是編碼
//輸出結束碼
this->OutputEncode(CODE_FINISH);
this->char_top++;
}

//強制清空緩沖區
this->Flush();

//釋放空間
this->ReleaseNode(this->root);
}

Hbtree * Huffman::NewNode(int value, int index, Hbtree *parent)
{
Hbtree *tmp=new Hbtree;
tmp->parent=parent;
tmp->child[0]=NULL;
tmp->child[1]=NULL;
tmp->count=(1 << SHRINK_FACTOR);
tmp->index=(index==0) ? 0 : 1;
tmp->value=value;

if(value!=NOT_CHAR)this->list[tmp->value]=tmp;
if(parent!=NULL)parent->child[tmp->index]=tmp;
return tmp;
}

void Huffman::ReleaseNode(Hbtree *node)
{
if(node!=NULL){
this->ReleaseNode(node->child[LEFT]);
this->ReleaseNode(node->child[RIGHT]);
delete node;
}
}

//輸出一位編碼
int Huffman::OutputBit(int bit)
{
unsigned char candidates[]={1,2,4,8,16,32,64,128};

if(bit!=0)
this->buffer[this->char_top] |= candidates[this->bit_top];
this->bit_top--;
if(this->bit_top < BOTTOM_BIT){
this->bit_top=TOP_BIT;
this->char_top++;

if(this->char_top >= BUFFER_SIZE){//輸出緩沖區
this->output(this->buffer,BUFFER_SIZE);
this->char_top=0;
}

this->buffer[this->char_top]=0;
}
return 0;
}

//輸出緩沖區
int Huffman::Flush()
{
this->output(this->buffer,this->char_top);
this->char_top=0;
return 0;
}

int Huffman::Encode(unsigned char c)
{
int value=c,
candidates[]={128,64,32,16,8,4,2,1},
i;

if(this->list[value]==NULL){//字元不存在於哈夫曼樹中
//輸出轉義碼
this->OutputEncode(CODE_ESCAPE);
//輸出字元
for(i=0;i<8;i++)this->OutputBit(value & candidates[i]);

this->InsertNewNode(value);

}else{
//輸出字元編碼
this->OutputEncode(value);

//重新調整哈夫曼樹
this->BalanceNode(this->list[value]->parent);
}

//重組哈夫曼樹
if(this->root->count>=this->max_count)
this->RearrangeTree();

return 0;
}

void Huffman::BalanceNode(Hbtree *node)
{
Hbtree *parent,*child,*brother;
int i,j;

parent=node->parent;
if(parent==NULL)return;//根節點無需調整

if(node->value==NOT_CHAR){//非葉子節點
child=node->child[LEFT]->count > node->child[RIGHT]->count ?
node->child[LEFT] : node->child[RIGHT];

if(child->count > parent->count - node->count){
//失衡

i=!(node->index);
j=child->index;
node->count=parent->count - child->count;
brother=parent->child[i];

node->child[j]=brother;
brother->index=j;
brother->parent=node;

parent->child[i]=child;
child->index=i;
child->parent=parent;
}
}
this->BalanceNode(parent);
}

//輸出一個字元的編碼
int Huffman::OutputEncode(int value)
{
int stack[CODE_FINISH+2],top=0;
Hbtree *tmp=this->list[value];

//輸出編碼
if(value<=MAX_VALUE){//字元
while(tmp!=NULL){
stack[top++]=tmp->index;
tmp->count++;
tmp=tmp->parent;
}
}else{//控制碼
while(tmp!=NULL){
stack[top++]=tmp->index;
tmp=tmp->parent;
}
}
top--;
while(top>0){
this->OutputBit(stack[--top]);
}

return 0;
}

void Huffman::PrintNode(Hbtree *node,int level)
{
int i;
if(node){
for(i=0;i<level*3;i++)printf(" ");
printf("%p P:%p L:%p R:%p C:%d",node,node->parent,node->child[0],node->child[1],node->count);
if(node->value!=NOT_CHAR)printf(" V:%d",node->value);
printf("\n");

this->PrintNode(node->child[LEFT],level+1);
this->PrintNode(node->child[RIGHT],level+1);
}
}

int Huffman::Encode(unsigned char *s, int len)
{
int i;
for(i=0;i<len;i++)this->Encode(s[i]);
return 0;
}

void Huffman::PrintTree()
{
this->PrintNode(this->root,0);
}

int Huffman::RecountNode(Hbtree *node)
{
if(node->value!=NOT_CHAR)return node->count;
node->count=
this->RecountNode(node->child[LEFT]) +
this->RecountNode(node->child[RIGHT]);
return node->count;
}

void Huffman::RearrangeTree()
{
int i,j,k;
Hbtree *tmp,*tmp2;

//所有非控制碼的計數值右移shrink_factor位,並刪除計數值為零的節點
for(k=0;k<=MAX_VALUE;k++){
if(this->list[k]!=NULL){
tmp=this->list[k];
tmp->count >>= this->shrink_factor;
if(tmp->count ==0){
this->list[k]=NULL;
tmp2=tmp->parent;
i=tmp2->index;
j=!(tmp->index);
if(tmp2->parent!=NULL){
tmp2->parent->child[i]=tmp2->child[j];
tmp2->child[j]->parent=tmp2->parent;
tmp2->child[j]->index=i;
}else{
this->root=tmp2->child[j];
this->current=this->root;
this->root->parent=NULL;
}
delete tmp;
delete tmp2;
}
}
}

//重新計數
this->RecountNode(this->root);

//重新調整平衡
for(i=0;i<=MAX_VALUE;i++){
if(this->list[i]!=NULL)
this->BalanceNode(this->list[i]->parent);
}
}

void Huffman::InsertNewNode(int value)
{
int i;
Hbtree *tmp,*tmp2;

//將字元加入哈夫曼樹
tmp2=this->list[CODE_FINISH];
tmp=this->NewNode(NOT_CHAR, tmp2->index, tmp2->parent);
tmp->child[LEFT]=tmp2;
tmp2->index=LEFT;
tmp2->parent=tmp;

tmp2=this->NewNode(value,RIGHT,tmp);
tmp->count=tmp->child[LEFT]->count+tmp->child[RIGHT]->count;
i=tmp2->count;
while((tmp=tmp->parent)!=NULL)tmp->count+=i;
//從底向上調整哈夫曼樹
this->BalanceNode(tmp2->parent);
}

int Huffman::Decode(unsigned char c)
{
this->Decode(c,7);
return 0;
}

int Huffman::Decode(unsigned char *s,int len)
{
int i;
for(i=0;i<len;i++)this->Decode(s[i]);
return 0;
}

int Huffman::Decode(unsigned char c, int start)
{
int value=c,
candidates[]={1,2,4,8,16,32,64,128},
i,j;
Hbtree *tmp;

if(this->finished)return 0;

i=start;
if(this->current==NULL){//轉義狀態下
while(this->remain >= 0 && i>=0){
if((candidates[i] & value) !=0){
this->literal |= candidates[this->remain];
}
this->remain--;
i--;
}

if(this->remain < 0){//字元輸出完畢

//輸出字元
this->OutputChar(this->literal);
//將字元插入哈夫曼樹
this->InsertNewNode(literal);
//重組哈夫曼樹
if(this->root->count>=this->max_count)
this->RearrangeTree();

//設置環境
this->current=this->root;
}
}else{
j=((value & candidates[i])!=0)?1:0;
tmp=this->current->child[j];
i--;
while(tmp->value==NOT_CHAR && i>=0){
j=((value & candidates[i])!=0)?1:0;
tmp=tmp->child[j];
i--;
}

if(tmp->value==NOT_CHAR){//中間節點
this->current=tmp;
}else{
if(tmp->value<=MAX_VALUE){//編碼內容
j=tmp->value;
this->OutputChar((unsigned char)j);

//修改計數器
tmp=this->list[j];
while(tmp!=NULL){
tmp->count++;
tmp=tmp->parent;
}
//調整平衡度
this->BalanceNode(this->list[j]->parent);

//重組哈夫曼樹
if(this->root->count>=this->max_count)
this->RearrangeTree();

//設置環境
this->current=this->root;
}else{
if(tmp->value==CODE_ESCAPE){//轉義碼
this->current=NULL;
this->remain=7;
this->literal=0;
}else{//結束碼
this->finished=true;
return 0;
}
}
}

}

if(i>=0)this->Decode(c,i);
return 0;
}

int Huffman::OutputChar(unsigned char c)
{
this->buffer[this->char_top++]=c;
if(this->char_top>=BUFFER_SIZE){//輸出緩沖區
this->output(this->buffer,BUFFER_SIZE);
this->char_top=0;
}
return 0;
}

========end of Huffman.cpp==================

========Huffman.h============================
// Huffman.h: interface for the Huffman class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(NULL)
#include <stdio.h>
#endif

#if !defined(AFX_HUFFMAN_H__B1F1A5A6_FB57_49B2_BB67_6D1764CC04AB__INCLUDED_)
#define AFX_HUFFMAN_H__B1F1A5A6_FB57_49B2_BB67_6D1764CC04AB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define MAX_COUNT 65536 //最大計數值,大於此值時
#define MAX_VALUE 255 //編碼的最大值
#define CODE_ESCAPE MAX_VALUE+1 //轉義碼
#define CODE_FINISH MAX_VALUE+2 //結束碼
#define LIST_LENGTH MAX_VALUE+3 //編碼列表長度
#define SHRINK_FACTOR 2 //減小的比例,通過右移位實現
#define LEFT 0 //左孩子索引
#define RIGHT 1 //右孩子索引
#define NOT_CHAR -1 //非字元

#define TOP_BIT 7 //字元最高位
#define BOTTOM_BIT 0 //字元最低位
#define BUFFER_SIZE 81920 //緩沖區大小

//輸出函數
typedef bool (Output)(unsigned char *s,int len);

//哈夫曼樹的節點定義
typedef struct Hnode{
int count;//計數器
int index;//父節點的孩子索引(0--左孩子,1--右孩子)
Hnode* child[2];
Hnode* parent;
int value;
}Hbtree;

class Huffman
{
private:
//輸出一個解碼的字元
int OutputChar(unsigned char c);
//從指定位置開始解碼
int Decode(unsigned char c,int start);
//插入一個新節點
void InsertNewNode(int value);
//重新調整哈夫曼樹構型
void RearrangeTree();
//對各節點重新計數
int RecountNode(Hbtree *node);
//列印哈夫曼樹節點
void PrintNode(Hbtree *node,int level);
//輸出一個值的編碼
int OutputEncode(int value);
//調節哈夫曼樹節點使之平衡
void BalanceNode(Hbtree *node);
//輸出一位編碼
int OutputBit(int bit);
//釋放哈夫曼樹節點
void ReleaseNode(Hbtree *node);
//新建一個節點
Hbtree *NewNode(int value,int index, Hbtree *parent);
//輸出函數地址
Output *output;
//哈夫曼樹根地址
Hbtree *root;
//哈夫曼編碼單元列表
Hbtree *list[LIST_LENGTH];
//輸出緩沖區
unsigned char buffer[BUFFER_SIZE];
//緩沖區頂
int char_top,bit_top;
//收縮哈夫曼樹參數
int max_count,shrink_factor;
//工作模式,true--編碼,false--解碼
bool mode;
//解碼的當前節點
Hbtree *current;
int remain;//當前字元剩餘的位數
unsigned char literal;//按位輸出的字元
bool finished;

public:

//解碼指定長度的字元串
int Decode(unsigned char *s,int len);
//解碼一個字元
int Decode(unsigned char c);
//列印哈夫曼樹
void PrintTree();
//編碼指定長度的字元串
int Encode(unsigned char *s,int len);
//編碼一個字元
int Encode(unsigned char c);
//清空緩沖區
int Flush();

//output指輸出函數,mode指工作模式,true--編碼,false--解碼
Huffman(Output *output,bool mode);

//析構函數
virtual ~Huffman();
};

#endif // !defined(AFX_HUFFMAN_H__B1F1A5A6_FB57_49B2_BB67_6D1764CC04AB__INCLUDED_)

================end of Huffman.h==================

祝你好運!

Ⅳ 簡述一下hdfs的數據壓縮演算法,工作中用的是哪種演算法,為什麼

1、在HDFS之上將數據壓縮好後,再存儲到HDFS
2、在HDFS內部支持數據壓縮,這里又可以分為幾種方法:
2.1、壓縮工作在DataNode上完成,這里又分兩種方法:
2.1.1、數據接收完後,再壓縮
這個方法對HDFS的改動最小,但效果最低,只需要在block文件close後,調用壓縮工具,將block文件壓縮一下,然後再打開block文件時解壓一下即可,幾行代碼就可以搞定
2.1.2、邊接收數據邊壓縮,使用第三方提供的壓縮庫
效率和復雜度折中方法,Hook住系統的write和read操作,在數據寫入磁碟之前,先壓縮一下,但write和read對外的介面行為不變,比如:原始大小為100KB的數據,壓縮後大小為10KB,當寫入100KB後,仍對調用者返回100KB,而不是10KB
2.2、壓縮工作交給DFSClient做,DataNode只接收和存儲
這個方法效果最高,壓縮分散地推給了HDFS客戶端,但DataNode需要知道什麼時候一個block塊接收完成了。
推薦最終實現採用2.2這個方法,該方法需要修改的HDFS代碼量也不大,但效果最高。

Ⅳ 如何用C語言實現數據壓縮

首先選擇一個壓縮演算法

然後按照演算法實現壓縮代碼,調用介面就可以
常見的 可以使用哈夫曼編碼壓縮,或者使用開源的壓縮代碼,比如lzo, gzip, lzma等等。

Ⅵ 壓縮演算法原理

哈夫曼
哈夫曼編碼是無損壓縮當中最好的方法。它使用預先二進制描述來替換每個符號,長度由特殊符號出現的頻率決定。常見的符號需要很少的位來表示,而不常見的符號需要很多為來表示。

哈夫曼演算法在改變任何符號二進制編碼引起少量密集表現方面是最佳的。然而,它並不處理符號的順序和重復或序號的序列。

2.1 原理
我不打算探究哈夫曼編碼的所有實際的細節,但基本的原理是為每個符號找到新的二進製表示,從而通常符號使用很少的位,不常見的符號使用較多的位。

簡短的說,這個問題的解決方案是為了查找每個符號的通用程度,我們建立一個未壓縮數據的柱狀圖;通過遞歸拆分這個柱狀圖為兩部分來創建一個二叉樹,每個遞歸的一半應該和另一半具有同樣的權(權是 ∑ N K =1 符號數 k , N 是分之中符號的數量,符號數 k 是符號 k出現的次數 )

這棵樹有兩個目的:

1. 編碼器使用這棵樹來找到每個符號最優的表示方法

2. 解碼器使用這棵樹唯一的標識在壓縮流中每個編碼的開始和結束,其通過在讀壓縮數據位的時候自頂向底的遍歷樹,選擇基於數據流中的每個獨立位的分支,一旦一個到達葉子節點,解碼器知道一個完整的編碼已經讀出來了。

壓縮後的數據流是 24 位(三個位元組),原來是 80 位( 10 個位元組)。當然,我應該存儲哈夫曼樹,這樣解碼器就能夠解碼出對應的壓縮流了,這就使得該例子中的真正數據流比輸入的流數據量大。這是相對較短的數據上的副作用。對於大數據量來說,上面的哈夫曼樹就不佔太多比例了。

解碼的時候,從上到下遍歷樹,為壓縮的流選擇從左 / 右分支,每次碰到一個葉子節點的時候,就可以將對應的位元組寫到解壓輸出流中,然後再從根開始遍歷。

2.2 實現
哈夫曼編碼器可以在基本壓縮庫中找到,其是非常直接的實現。

這個實現的基本缺陷是:

1. 慢位流實現

2. 相當慢的解碼(比編碼慢)

3. 最大的樹深度是 32 (編碼器在任何超過 32 位大小的時候退出)。如果我不是搞錯的話,這是不可能的,除非輸出的數據大於 2 32位元組。

另一方面,這個實現有幾個優點:

1. 哈夫曼樹以一個緊密的形式每個符號要求 12 位(對於 8 位的符號)的方式存儲,這意味著最大的頭為 384 。

2. 編碼相當容易理解

哈夫曼編碼在數據有噪音的情況(不是有規律的,例如 RLE )下非常好,這中情況下大多數基於字典方式的編碼器都有問題。

Ⅶ 多媒體數據壓縮的兩種基本方法是什麼

從資訊理論的角度看,壓縮就是去掉信息中的冗餘,即保留不確定的信息,去除確定的信 息.多媒體技術中常用的數據壓縮演算法分為兩大類:無損壓縮和有損壓縮.冗餘壓縮法去掉 或減少數據中的冗餘,但這些冗餘量是可以重新插人到數據中的,因而不會產生失真.其壓 縮效率通常較低; 有損壓縮則採用一些高效的有限失真數據壓縮演算法, 大幅度減少多媒體中 的冗餘信息,其壓縮效率遠高於無損壓縮.無損壓縮.這類方法廣泛用於文本數據,程序和 特殊應用場合的圖像數據(如指紋圖像,醫學圖像等)的壓縮.有損壓縮廣泛應用於語音,圖 像和視頻數據的壓縮.常見的編碼方法可以

Ⅷ 求C++簡單文件壓縮程序,用基本演算法實現

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void main()
{
ifstream infile("c:\\1.txt");//自己改文件名
ofstream outfile("c:\\2.txt");
char cCurrent,cPre;
int iCount=0;
cPre=-1;
while(infile>>cCurrent)
{
if(cCurrent=='\n') continue;
if(cPre==-1) cPre=cCurrent;
if(cPre==cCurrent)
{
iCount++;
}
else
{
if(cPre>='0'&&cPre<='9')
outfile<<iCount<<'*'<<cPre<<' ';
else
outfile<<iCount<<cPre<<' ';
cPre=cCurrent;
iCount=1;
}

}
if(cPre>='0'&&cPre<='9')
outfile<<iCount<<'*'<<cPre<<' ';
else
outfile<<iCount<<cPre<<' ';
infile.close();
outfile.close();

}

Ⅸ 數據壓縮

數據壓縮技術主要研究數據的表示、傳輸和轉換方法,目的是減少數據所佔據的存儲空間和縮短數據傳輸時所需要的時間。

衡量數據壓縮的3個主要指標:一是壓縮前後所需的信息存儲量之比要大;二是實現壓縮的演算法要簡單,壓縮、解壓縮速度快,要盡可能做到實時壓縮和解壓縮;三是恢復效果要好,要盡可能完全恢復原始數據。

數據壓縮主要應用於兩個方面。一是傳輸:通過壓縮發送端的原始數據,並在接收端進行解壓恢復,可以有效地減少傳輸時間和增加信道帶寬。二是存儲:在存儲時壓縮原始數據,在使用時進行解壓,可大大提高存儲介質的存儲量。

數據壓縮按照壓縮的失真度分成兩種類型:一種叫作無損壓縮,另一種叫作有損壓縮。

無損壓縮是指使用壓縮後的數據進行重構(或者叫作還原、解壓縮),重構後的數據與原來的數據完全相同;無損壓縮用於要求重構的信號與原始信號完全一致的場合。一個很常見的例子是磁碟文件的壓縮。根據目前的技術水平,無損壓縮演算法一般可以把普通文件的數據壓縮到原來的1/4~1/2。一些常用的無損壓縮演算法有霍夫曼(Huffman)演算法、算術演算法、遊程演算法和LZW(Lenpel-Ziv & Welch)壓縮演算法。

1)霍夫曼演算法屬於統計式壓縮方法,其原理是根據原始數據符號發生的概率進行編碼。在原始數據中出現概率越高的符合,相應的碼長越短,出現概率越少的符合,其碼長越長。從而達到用盡可能少的符號來表示原始數據,實現對數據的壓縮。

2)算術演算法是基於統計原理,無損壓縮效率最高的演算法。即將整段要壓縮的數據映射到一段實數半封閉的范圍[0,1)內的某一區段。該區段的范圍或寬度等於該段信息概率。即是所有使用在該信息內的符號出現概率全部相乘後的概率值。當要被編碼的信息越來越長時,用來代表該信息的區段就會越來越窄,用來表示這個區段的位就會增加。

3)遊程演算法是針對一些文本數據特點所設計的壓縮方法。主要是去除文本中的冗餘字元或位元組中的冗餘位,從而達到減少數據文件所佔的存儲空間。壓縮處理流程類似於空白壓縮,區別是在壓縮指示字元之後加上一個字元,用於表明壓縮對象,隨後是該字元的重復次數。本演算法具有局限性,很少單獨使用,多與其他演算法配合使用。

4)LZW演算法的原理是用字典詞條的編碼代替在壓縮數據中的字元串。因此字典中的詞條越多,壓縮率越高,加大字典的容量可以提高壓縮率。字典的容量受計算機的內存限制。

有損壓縮是指使用壓縮後的數據進行重構,重構後的數據與原來的數據有所不同,但不影響人對原始資料表達的信息造成誤解。有損壓縮適用於重構信號不一定非要和原始信號完全相同的場合。例如,圖像和聲音的壓縮就可以採用有損壓縮,因為其中包含的數據往往多於我們的視覺系統和聽覺系統所能接收的信息,丟掉一些數據而不至於對聲音或者圖像所表達的意思產生誤解,但可大大提高壓縮比。

Ⅹ 如何寫壓縮軟體,運用哈夫曼演算法實現

到文件壓縮大家很容易想到的就是rar,zip等我們常見的壓縮格式。然而,還有一種就是大家在學習數據結構最常見到的哈夫曼樹的數據結構,以前還不知道他又什麼用,其實他最大的用途就是用來做壓縮,也是一些rar,zip壓縮的祖先,稱為哈弗曼壓縮(什麼你不知道誰是哈弗曼,也不知道哈弗曼壓縮,不急等下介紹)。

隨著網路與多媒體技術的興起,人們需要存儲和傳輸的數據越來越多,數據量越來越大,以前帶寬有限的傳輸網路和容量有限的存儲介質難以滿足用戶的需求。

特別是聲音、圖像和視頻等媒體在人們的日常生活和工作中的地位日益突出,這個問題越發顯得嚴重和迫切。如今,數據壓縮技術早已是多媒體領域中的關鍵技術之一。

一、什麼是哈弗曼壓縮

Huffman(哈夫曼)演算法在上世紀五十年代初提出來了,它是一種無損壓縮方法,在壓縮過程中不會丟失信息熵,而且可以證明Huffman演算法在無損壓縮演算法中是最優的。Huffman原理簡單,實現起來也不困難,在現在的主流壓縮軟體得到了廣泛的應用。對應用程序、重要資料等絕對不允許信息丟失的壓縮場合,Huffman演算法是非常好的選擇。

二、怎麼實現哈弗曼壓縮

哈夫曼壓縮是個無損的壓縮演算法,一般用來壓縮文本和程序文件。哈夫曼壓縮屬於可變代碼長度演算法一族。意思是個體符號(例如,文本文件中的字元)用一個特定長度的位序列替代。因此,在文件中出現頻率高的符號,使用短的位序列,而那些很少出現的符號,則用較長的位序列。

故我們得了解幾個概念:

1、二叉樹:在計算機科學中,二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作「左子樹」(left subtree)和「右子樹」(right subtree)。2、哈夫曼編碼(Huffman Coding):是一種編碼方式,哈夫曼編碼是可變字長編碼(VLC)的一種。uffman於1952年提出一種編碼方法,該方法完全依據字元出現概率來構造異字頭的平均長 度最短的碼字,有時稱之為最佳編碼,一般就叫作Huffman編碼。三、哈夫曼編碼生成步驟:

①掃描要壓縮的文件,對字元出現的頻率進行計算。

②把字元按出現的頻率進行排序,組成一個隊列。

③把出現頻率最低(權值)的兩個字元作為葉子節點,它們的權值之和為根節點組成一棵樹。

④把上面葉子節點的兩個字元從隊列中移除,並把它們組成的根節點加入到隊列。

⑤把隊列重新進行排序。重復步驟③④⑤直到隊列中只有一個節點為止。

⑥把這棵樹上的根節點定義為0(可自行定義0或1)左邊為0,右邊為1。這樣就可以得到每個葉子節點的哈夫曼編碼了。

既如 (a)、(b)、(c)、(d)幾個圖,就可以將離散型的數據轉化為樹型的了。

如果假設樹的左邊用0表示右邊用1表示,則每一個數可以用一個01串表示出來。

則可以得到對應的編碼如下:
1-->110
2-->111
3-->10
4-->0
每一個01串,既為每一個數字的哈弗曼編碼。
為什麼能壓縮:
壓縮的時候當我們遇到了文本中的1、2、3、4幾個字元的時候,我們不用原來的存儲,而是轉化為用它們的01串來存儲不久是能減小了空間佔用了嗎。(什麼01串不是比原來的字元還多了嗎?怎麼減少?)大家應該知道的,計算機中我們存儲一個int型數據的時候一般式佔用了2^32-1個01位,因為計算機中所有的數據都是最後轉化為二進制位去存儲的。所以,想想我們的編碼不就是只含有0和1嘛,因此我們就直接將編碼按照計算機的存儲規則用位的方法寫入進去就能實現壓縮了。
比如:
1這個數字,用整數寫進計算機硬碟去存儲,佔用了2^32-1個二進制位
而如果用它的哈弗曼編碼去存儲,只有110三個二進制位。
效果顯而易見。

熱點內容
python文件刪除一行 發布:2025-05-14 08:06:58 瀏覽:721
如何下載奧特曼高級化3安卓版 發布:2025-05-14 07:47:31 瀏覽:346
qml文件修改後編譯未生效 發布:2025-05-14 07:31:00 瀏覽:331
內到內演算法 發布:2025-05-14 07:29:11 瀏覽:34
文件夾名字不顯示 發布:2025-05-14 07:27:47 瀏覽:775
oracle的資料庫驅動jar 發布:2025-05-14 07:23:20 瀏覽:556
我的世界電腦版伺服器手機版能進嗎 發布:2025-05-14 07:22:01 瀏覽:679
達內培訓php多少錢 發布:2025-05-14 07:19:10 瀏覽:27
python位元組轉字元串 發布:2025-05-14 07:06:35 瀏覽:423
subplotpython 發布:2025-05-14 06:53:51 瀏覽:662