旋转门压缩与解压
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法原理:(非常清晰)
//门一旦打开就不关闭,是指在一个压缩段内。
说明:该算法的压缩效果和数据有很大关系,一般测试时用正弦波数据,压缩效果很好,如果用随机数,基本不会压缩。
==============================
程序说明:
E(压缩精度)的值要根据待压缩的数值来定,如果E的值太小,解压误差会很小,但压缩率低。如果E的值太大,压缩比非常高,100MB的文件可能就只有几M,但解压误差非常大。所以E要多试几次取一个比较合理的值。
5.解压过程:(线性插值)有起点和终点坐标可以求出线段的公式,然后根据某点x轴坐标求出其对应的y的值,也就是实际的值。
=====================
[cpp]view plain copy print?
1.#include
2.
3.#define MAX_DOUBLE 1.79769e+308
4.#define E 3
5.
6.struct point
7.{
8.int x, y;
9.};
10.
11.void compress()
12.{
13.FILE * fin = fopen("rand.txt", "r");
14.FILE * fout = fopen("out.txt", "w");
15.
16.//上门和下门,初始时门是关着的
17.double up_gate = -MAX_DOUBLE;
18.double down_gate = MAX_DOUBLE;
19.
20.//当前数据的上斜率和下斜率
21.double now_up, now_down;
22.
23.int data; //当前读取到的数据
24.int last_read_data; //当前数据的前一个数据
25.int last_stored_data; //最近保存的点
26.
27.//read and save the first data
28.fscanf(fin, "%d", &last_stored_data);
29.fprintf(fout, "0 %d ", last_stored_data);
30.
st_read_data = last_stored_data;
32.
33.int last_stored_t = 0; //最近保存数据的时间,init 0
34.
35.//循环处理数据
36.int t=0;
37.while(++t, fscanf(fin, "%d", &data) != EOF)
38.{
39.now_up = double(data-last_stored_data-E) / (t-last_stored_t);
40.if(now_up > up_gate)
41.up_gate = now_up;
42.
43.now_down = double(data-last_stored_data+E) / (t-last_stored_t);
44.if(now_down < down_gate)
45.down_gate = now_down;
46.
47.if(up_gate >= down_gate)
48.{
49.//保存前一个点
50.fprintf(fout, "%d %d ", t-1, last_read_data);
51.
st_stored_t = t-1; //修改最近保存数据时间点
st_stored_data = last_read_data;
54.
55.//初始化两扇门为当前点与上个点的斜率
56.up_gate = double(data-last_stored_data-E);
57.down_gate = double(data-last_stored_data+E);
58.}
st_read_data = data;
60.}
61.// sava end point
62.fprintf(fout, "%d %d ", t-1, last_read_data);
63.
64.fclose(fin);
65.fclose(fout);
66.}
67.
68.void uncompress()
69.{
70.FILE * fin = fopen("out.txt", "r");
71.FILE * fout = fopen("src.txt", "w");
72.
73.point a,b;
74.fscanf(fin, "%d %d", &a.x, &a.y);
75.
76.while(fscanf(fin, "%d %d", &b.x,&b.y) != EOF)
77.{
78.//Step.1
79.fprintf(fout, "%d ", a.y);
80.
81.//Step.2
82.if(a.x+1 != b.x)
83.{
84.double k = double(b.y - a.y) / (b.x - a.x); //计算斜率
85.for(int i=a.x+1; i 86.{ 87.//线性插值求被压缩掉的数据 88.fprintf(fout, "%.0lf ", k*(i-a.x) + a.y); 89.} 90.} 91. 92. a.x = b.x; 93. a.y = b.y; 94.} 95.fprintf(fout, "%d ", b.y); 96.fclose(fin); 97.fclose(fout); 98.} 99. 100.i nt main(void) 101.{ 102.c ompress(); 103.u ncompress(); 104.r eturn 0; 105.} 其实把current , lastRead, lastStored定义为Point类型程序会更清晰。 下面上一下压缩效果图,界面是用.Net中的Chart控件做的,用法很简单,如果想直观的看到结果,你们可以托一个控件上去看看效果~ 挺好玩的。