zoukankan      html  css  js  c++  java
  • 【转】旋转门算法

    //门一旦打开就不关闭,是指在一个压缩段内。

    说明:该算法的压缩效果和数据有很大关系,一般测试时用正弦波数据,压缩效果很好,如果用随机数,基本不会压缩。

    ==============================

    程序说明:

     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

  • 相关阅读:
    python版本升级及pip部署方法
    Redis集群管理(二)
    UP UP UP!(dp)
    One Way Roads(搜索)
    Back to Underworld(搜索)
    队列链表实现以及有序表的合并
    第八届郑州轻工业学院ACM(程序设计大赛)校内预选赛
    Modulo Sum(背包 + STL)
    Co-prime Array&&Seating On Bus(两道水题)
    Hard Process(二分)
  • 原文地址:https://www.cnblogs.com/budapeng/p/4963350.html
Copyright © 2011-2022 走看看