
//門一旦打開就不關閉,是指在一個壓縮段內。
說明:該算法的壓縮效果和數據有很大關系,一般測試時用正弦波數據,壓縮效果很好,如果用隨機數,基本不會壓縮。
==============================
程序說明:
E(壓縮精度)的值要根據待壓縮的數值來定,如果E的值太小,解壓誤差會很小,但壓縮率低。
如果E的值太大,壓縮比非常高,100MB的文件可能就只有幾M,但解壓誤差非常大。所以E要多試幾次取一個比較合理的值。
5.解壓過程:(線性插值)有起點和終點坐標可以求出線段的公式,然后根據某點x軸坐標求出其對應的y的值,也就是實際的值。
=====================
#include <stdio.h>
#define MAX_DOUBLE 1.79769e+308
#define E 3
struct point
{
int x, y;
};
void compress()
{
FILE * fin = fopen("rand.txt", "r");
FILE * fout = fopen("out.txt", "w");
//上門和下門,初始時門是關着的
double up_gate = -MAX_DOUBLE;
double down_gate = MAX_DOUBLE;
//當前數據的上斜率和下斜率
double now_up, now_down;
int data; //當前讀取到的數據
int last_read_data; //當前數據的前一個數據
int last_stored_data; //最近保存的點
//read and save the first data
fscanf(fin, "%d", &last_stored_data);
fprintf(fout, "0 %d ", last_stored_data);
last_read_data = last_stored_data;
int last_stored_t = 0; //最近保存數據的時間,init 0
//循環處理數據
int t=0;
while(++t, fscanf(fin, "%d", &data) != EOF)
{
now_up = double(data-last_stored_data-E) / (t-last_stored_t);
if(now_up > up_gate)
up_gate = now_up;
now_down = double(data-last_stored_data+E) / (t-last_stored_t);
if(now_down < down_gate)
down_gate = now_down;
if(up_gate >= down_gate)
{
//保存前一個點
fprintf(fout, "%d %d ", t-1, last_read_data);
last_stored_t = t-1; //修改最近保存數據時間點
last_stored_data = last_read_data;
//初始化兩扇門為當前點與上個點的斜率
up_gate = double(data-last_stored_data-E);
down_gate = double(data-last_stored_data+E);
}
last_read_data = data;
}
// sava end point
fprintf(fout, "%d %d ", t-1, last_read_data);
fclose(fin);
fclose(fout);
}
void uncompress()
{
FILE * fin = fopen("out.txt", "r");
FILE * fout = fopen("src.txt", "w");
point a,b;
fscanf(fin, "%d %d", &a.x, &a.y);
while(fscanf(fin, "%d %d", &b.x,&b.y) != EOF)
{
//Step.1
fprintf(fout, "%d ", a.y);
//Step.2
if(a.x+1 != b.x)
{
double k = double(b.y - a.y) / (b.x - a.x); //計算斜率
for(int i=a.x+1; i<b.x; i++)
{
//線性插值求被壓縮掉的數據
fprintf(fout, "%.0lf ", k*(i-a.x) + a.y);
}
}
a.x = b.x;
a.y = b.y;
}
fprintf(fout, "%d ", b.y);
fclose(fin);
fclose(fout);
}
int main(void)
{
compress();
uncompress();
return 0;
}
其實把current , lastRead, lastStored定義為Point類型程序會更清晰。
下面上一下壓縮效果圖,界面是用.Net中的Chart控件做的,用法很簡單,如果想直觀的看到結果,你們可以托一個控件上去看看效果~ 挺好玩的。

上面的曲線是原數據,總共是800個點,壓縮后可以看到,儲存的點屈指可數。
從圖中可以看出對均勻變化的數據壓縮效果是非常好的,但是隨機數基本上不會被壓縮,圖就不貼了。
轉自:http://blog.csdn.net/gneveek/article/details/7821151
