精华内容
下载资源
问答
  • 摘要:分形图像压缩编码是近年来产生的新的图像压缩编码技术,由于其具有极高的压缩比而获得广泛的关注。主要讨论了图像小波域的去噪问题以及如何将小波域的去噪与分形图像压缩方法结合起来,以获得良好的编码效率和...
  • 分形图像压缩技术具有极高的压缩比、快速的解压缩速度 ,在图像通信、多媒体、互联网中得到了广泛的应用。分形几何理论研究的是很不规则的如粗糙、不光滑、破碎、扭曲、缠绕等且有自相似性的形状。分形具有精细的结构...
  • rar压缩软件.rar

    2016-02-13 10:52:44
    可以 WinRAR,它支持更多的压缩文件类型,包括 RAR 和 ZIP 格式。 WinRAR 提供了图形用户界面和命令行模式。虽然控制台 RAR 和图形界面 WinRAR 有相似的命令行语法,但是它们还有有一些不同。所以推荐使用此 ...
  • 一、LZW的介绍 定义:LZW算法又叫“串表压缩算法”就是通过建立一个字符串表,用较短的代码来表示较长...即对于数据流中连续重复出现的字节和字串,LZW压缩技术具有很高的压缩比。 1、LZW编码 (Encoding) 的核心思...

    一、LZW的介绍

    定义:LZW算法又叫“串表压缩算法”就是通过建立一个字符串表,用较短的代码来表示较长的字符串来实现压缩。

    特点:LZW和哈夫曼编码一样,是无损压缩中的一种。该算法通过建立字典(HashMap),实现字符重用与编码,适用于source中重复率很高的文本压缩。即对于数据流中连续重复出现的字节和字串,LZW压缩技术具有很高的压缩比。

    1、LZW编码 (Encoding) 的核心思想其实比较简单,就是把出现过的字符串映射到记号上,这样就可能用较短的编码来表示长的字符串,实现压缩,例如对于字符串:

    2、字典的生成

    为什么第一个AB不也用2表示?即表示为222,这样不又节省了一个记号?这个问题实际上引出的是LZW的一个核心思想,即压缩后的编码是自解释 (self-explaining) 的。什么意思?即字典是不会被写进压缩文件的,在解压缩的时候,一开始字典里除了默认的0->A和1->B之外并没有其它映射,2->AB是在解压缩的过程中一边加入的。这就要求压缩后的数据自己能告诉解码器,完整的字典,例如2->AB是如何生成的,在解码的过程中还原出编码时用的字典。

    故编码或解码完毕,字典都会被弃用。

    3、现实的LZW算法的初始字典就是Ascii表,以此为扩展。

    当然在真正的LZW算法中A和B不会用数字0和1表示,而是它们的ASCII值。实际上LZW初始会有一个默认的字典,包含了所有256个8bit字符,单个字符的记号就是它自身,用数字表示就是ASCII值。在此基础上,编码过程中加入的新的记号的映射,从256开始,称为扩展表(Extended Dictionary)。在这个例子里是为了简单起见,只有两个基础字符,所以规定0表示A,1表示B,从记号2开始就是扩展项了。

    二、LZW压缩算法,EnCodeing

    编码器从原字符串不断地读入新的字符,并试图将单个字符或字符串编码为记号 (Symbol)。这里我们维护两个变量,一个是P (Previous),表示手头已有的,还没有被编码的字符串,一个是C (current),表示当前新读进来的字符

    1、编码算法

     1. 初始状态,字典为Ascii表。此时P和C都是空的。
     2. 读入新的字符C,与P合并形成字符串P+C。
     3. 在字典里查找P+C,如果:
        - P+C在字典里,P=P+C。
        - P+C不在字典里,将P的记号输出;在字典中为P+C建立一个记号映射;更新P=C。
     4. 返回步骤2重复,直至读完原字符串中所有字符。

    以上表示的是编码中间的一般过程,在收尾的时候有一些特殊的处理,即步骤2中,如果到达字符串尾部,没有新的C读入了,则将手头的P对应的记号输出,结束。

    编码过程的核心就在于第3步,我们需要理解P究竟是什么。P是当前维护的,可以被编码为记号的子串。注意P是可以被编码为记号,但还并未输出。新的字符C不断被读入并添加到P的尾部,只要P+C仍然能在字典里找到,就不断增长更新P=P+C,这样就能将一个尽可能长的字串P编码为一个记号,这就是压缩的实现。当新的P+C无法在字典里找到时,我们没有办法,输出已有的P的编码记号,并为新子串P+C建立字典表项。然后新的P从单字符C开始,重新增长,重复上述过程。

    2、算法流程图

    3、直接上Java代码

    编码是string到int的映射,默认字典是256个Ascii码。

    //1、编码,String到int的映射
    public List<Integer> encode(String data)
    { 
        System.out.println("原字符串:"+data);
        System.out.print("编码流:");
        List<Integer> result = new ArrayList<>();//存放编码流
        	
        //首先要初始化默认字典,即Ascii表。
        int codeValue = 256;
        HashMap<String,Integer> dic = new HashMap<>();
        for(int i =0;i<codeValue;i++)
        {
            dic.put((char)i+"", i);
        }
        
        String pre ="";//词组前缀,表示当前还未被编号的子串
        String str;//pre+c
        for(char c:data.toCharArray())
        {
        	str = pre+c;
        	if(dic.containsKey(str))
        	{
        	   pre = str;
        	}
        	else 
        	{
    	     dic.put(str, codeValue++);//为字典添加pre+cd的新映射,扩展码从256开始递增
    	     result.add(dic.get(pre));//输出pre的编码
    	     System.out.print(dic.get(pre)+",");
    	     pre = c+"";//更新pre=c
    	}
        }
        	
        //如果到达字符串尾部,没有新的C读入了,则将手头的Pre对应的编码输出,结束。
        if(!pre.equals(""))
        {
            result.add(dic.get(pre));
            System.out.print(dic.get(pre));
        }
                	
            return result;
    }

    输出结果:

    三、LZW解压缩算法,DeCodeing

    编码的逆过程,若编码是string到int的映射,我们可以将解码过程描述为int到string的映射。

    解压的基本思路也是知道一个基本的Ascii码表,然后一边读取一边解码,然后扩充码表

    解码器的输入是压缩后的数据,即记号流 (Symbol Stream)。类似于编码,我们仍然维护两个变量pW (previous word) 和cW (current word),后缀W的含义是word,实际上就是记号 (Symbol),一个记号就代表一个word,或者说子串。pW表示之前刚刚解码的记号;cW表示当前新读进来的记号。

    注意cW和pW都是记号,我们用Str(cW)和Str(pW)表示它们解码出来的原字符串。

    1、解码算法

    1. 初始状态,字典为Ascii表。pW和cW都是空的。
    2. 读入第一个的符号cW,解码输出。注意第一个cW肯定是能直接解码的,而且一定是单个字符。
    3. 赋值pW=cW。
    4. 读入下一个符号cW。
    5. 在字典里查找cW,如果:
       a. cW在字典里:
         (1) 解码cW,即输出 Str(cW)。
         (2) 令P=Str(pW),C=Str(cW)的**第一个字符**。
         (3) 在字典中为P+C添加新的记号映射。
       b. cW不在字典里:
         (1) 令P=Str(pW),C=Str(pW)的**第一个字符**。
         (2) 在字典中为P+C添加新的记号映射,这个新的记号一定就是cW。
         (3) 输出P+C。
    6. 返回步骤3重复,直至读完所有记号。

    注意步骤5中的P+C的构成方式恰好对应编码过程中p+c不在字典中而添加新映射的情况。

    编码和解码都是从前往后步步推进的,同时生成字典,所以解码的过程也是一个不断还原编码字典的过程。解码器一边解码,向后推进,一边在之前已经解出的原始数据上重现编码的过程,构建出编码时用的字典。

    2、算法流程图

    3、直接上Java代码

    //2、解码,编码的逆过程,int到String的映射
    public String decode(List<Integer> array)
     {
         StringBuilder result = new StringBuilder();
         //同样要初始化Ascii字典,只是映射反过来为编码int指向String
         int deCode = 256;
         HashMap<Integer, String> dic = new HashMap<Integer, String>();
         for (int i = 0; i < 256; i++) 
    	dic.put(i, (char)i + "");
    		
         String p = "";//已经解码的字符串
         String c = "";//当前编码的字符串
         for (int code : array) 
        {
    	if(dic.containsKey(code)) 
    	{
    	   c = dic.get(code);
    	} 
            else 
    	   if (code == deCode)//解码比编码有一步的延迟,该编码即将加入映射
    	   {
    		 c = c + c.charAt(0);//c的第一个字符就是p的第一个字符
    		 System.out.println("code == deCode");
    	   }
    	   else 
    	       System.out.println("bad Code!");
    			
    	   if (!p.equals("")) 
               {
    		dic.put(deCode++, p + c.charAt(0));
    	   }
    			
    		result.append(c);
    		p = c;
          }
    
          System.out.println("++++++++++++++++++");
          System.out.println("解码后:"+result);
          return result.toString();
    }

    输出结果:

    四、LZW总结

    LZW算法的特殊之处在于,它提供了一种方式,使得压缩后的编码能够唯一地反推出编码过程中建立的字典,从而不必将字典本身写入压缩文件。试想,如果字典也需要写入压缩文件,那它占据的体积本身就会很大,可能到最后起不到压缩的效果。

     

    参考链接:感谢前辈的博客!

    LZW压缩算法原理解析

    Java实现LZW算法

     

    展开全文
  • * 获得类似工具更好的压缩率,使用'固实'压缩 * 身份校验(只有注册版本可用) * 自解压压缩文件和分卷压缩(SFX) * 对物理损伤的压缩文件的恢复能力 * 锁定,密码,文件顺序列表,文件安全和更多…… ...
  • 定义了激光光束衍射远场光斑压缩前后的能量以及能量密度来衡量超衍射极限激光光束的质量。通过利用反向传递算法设计了合适的补偿相位板,不但对准直放大的单一横模激光光束进行小于光学衍射极限的发散度的压缩,...
  • 1.图的定义 2.算法设计需要考虑什么呢? 3.遍历图的基本方法: 4.问题思考 5.最短路径问题解法 6.邻接矩阵 7.邻接矩阵存储结构定义 8.建立图的邻接矩阵 9.特殊矩阵的压缩存储 分析: 前言 图结构是一种...

    开发工具与关键技术:数据结构与算法

    作者:陈芝番

    撰写时间:2020.4.26

    目录

    前言

    1.图的定义

    2.算法设计需要考虑什么呢?

    3.遍历图的基本方法:

    4.问题思考

    5.最短路径问题解法

    6.邻接矩阵

    7.邻接矩阵存储结构定义

    8.建立图的邻接矩阵

    9.特殊矩阵的压缩存储

    分析:

    前言

    图结构是一种比树型结构更为复杂的非线性结构,任意一个节点都可以有任意多个前驱和后继。图结构是一种重要的数据结构,对我们普遍的人来说,图是一种设计和规划等等,而图也可以是一个结构图,对图进行分析,验算,数据元素之间的关系。所谓数组,是有序的元素序列,用于存储多个相同类型数据的集合。

    1.图的定义

    图是由顶点和边组成,顶点表示图的数据元素,边表示数据元素之间的关系。

    图的遍历:从图中某一顶点出发遍历图中其余顶点,且使每一顶点仅被访问一次。

    若图中表示边的顶点对是无序的,即称无向边,则图为无向图。

    若图中表示变的顶点对是有序的,即称有向边,则图为有向图。

    其中图又有完全图,稠密图,稀疏图。若无向图有1/2n(n-1)条边,即图中每对顶点之间都有一条边,即称该无向图为无向完全图。若有向图中有n(n-1)条孤,即图中每对顶点之间都有方向相反的两条孤。则称该有向图为有向完全图。有很少边的图或孤的图称为稀疏图,反之称为稠密图。

    当然还有连通图,连通分量;强连通图,强连通分量;权,网等等。

    图的存储结构比线性表和树的结构来说更为复杂,既要存储所有顶点的信息,又要存储顶点与顶点之间的所有关系,也就是边的信息。我们常说的“顶点的位置”和邻接点只是一个相对概念,图上任一顶点都可以看做初始顶点,任一顶点邻接点之间不存在次序关系。

    2.算法设计需要考虑什么呢

    需要考虑三个问题

    • 算法的参数要指定访问的第一个顶点;
    • 要考虑遍历路径可能出现的死循环问题;
    • 要使一个顶点的所有邻接顶点按照某种次序被访问。

    3.遍历图的基本方法

    (1)深度优先搜索:

    算法:

    //从第i个顶点出发

    Int visited[NAX_VEX]={0};
    Void Dfs_m(Mgraph*G,int i){
    Printf(“%3c”,G->vexs[i]);//访问顶点
    visited[i]=1;
    For(j=0;j<VEX_NUM;j++)
    If((G->arcs[i][j]==1)&&(!visited[j]))
    Dfs_m(G,j);
    }

    (2)广度优先搜索。

    4.问题思考

    从第i个顶点出发深度优先遍历以邻接表表示的图的算法

    如下:

    Typedef emnu {FALSE,TRUE}BOOLEAN;
    BOOLEAN Visited[MAX_VEX];
    Void DFS (ALGraph *G,int v)
    {
    linkNode*p;
    Visited[v]=TRUE;
    Visited(v);//访问顶点
    P= G->AdjList[v].firstarc;
    While(p!= NULL)
    {
    If(!Visited[p->adjvex])
    {
    DFS(G,P->ajdvex);
    }
    P=p->nextarc;
    }
    }

    5.最短路径问题解法

    边上权值非负情形的单源最短路径问题

    ---Dijkstra算法

    初始化s--{V0};
    Dist[j]--Gn.arcs[0][j],path[j],--0或-1
    {j=1,2,......,n-1}

    求出最短路径的长度:

    Dist[k]--min{dist[i]},i(-V-s;
    
    -SU{k};

    修改:

    Dist[j]--min{dist[j],dist[k]+Gn.arcs[k][j]};
    
    Path[j]--k;对于每一个j(-V-S;

    判断:

    若S=V或也无顶点可加入到S中,则算法结束,否则转(1)。

    所有顶点之间的最短路径

    ---Floyd算法

    Void Floyd (int dis [n+1][n+1],int path[n+1][n+1],int n)
    {
    Int i,j,k;
    For(k=1;k<=n;k++)
    For(i = 1;i<=n;i++)
    For(j=1;j<=n;j++)
    If(dis[i][k]+dis[k][j]<dis[i][j]
    {
    Dis[i][j] = dis[i][k]+dis[k][j]);
    Path[i][j]=k;
    }
    }

    6.邻接矩阵

    邻接矩阵采用两个数组来表示图,一个一维数组,存储图中所有顶点的信息,另一个是二维数组,即邻接矩阵,存储顶点之间的关系。

    7.邻接矩阵存储结构定义

    Typedef  char  VertexType;
    Typedef  int EdgeType;
    //定义图结构,用邻接矩阵存储
    Typedef  struct {
    VertexType vex[Max Vex];//顶点集合
    EdgeType arc[Max Vex][MaxVex];//边集合
    Int numVertex,numEdge;//图中实际的顶点数和边数
    } MGraph;
    

    8.建立图的邻接矩阵

    建立无向图邻接矩阵算法描述如下:

    Void Creat (MGraph*G)
    {
    Int i ,j,k;
    Printf(“输入顶点数和边数:\n”);
    Scanf(“%d,%d,&G->numVertex,&G->numEdge);
    Getchar();
    Printf(“输入顶点的集合:\n”);
    //输入顶点信息
    For(i=0;i<G->numVertex;i++)
    Scanf(“%c,&G->vex[i]);
    For(i=0;i<G->numVertex;i++)
    For(j=0;j<G->numVertex;j++)
    G->arc[i][j]=0;
    Getchar();
    For(k=0;k<G->numEdge;k++)
    {
    Printf(“请输入边(i,j):\n”);
    Scanf(“%d,%d”,&i,&j);
    G->arc[i][j]=1;
    G->arc[j][i]=1;
    }
    }

    即算法GreatMgraph的时间复杂度是O(n^2)。

    9.特殊矩阵的压缩存储

    所谓特殊矩阵是指矩阵中值相同的元素或者零元素的分布有一定规律。如对称矩阵,三角矩阵和对角矩阵等。

    • 对称矩阵

    对于一个n阶矩阵A中的元素满足,ai = aj(0《i《n ,0《j 《n),即称A为对称矩阵。

    压缩存储结构

    假设用一个一维数组B[n(n+1)/2]来存储n阶对称矩阵A的压缩存储结构。即存储对应的关系如下:

    • 三角矩阵

    当一个方阵An*n的主对角线以上或下的所有元素皆为常数时,该矩阵称为三角矩阵。

    紧接三角矩阵定义,三角矩阵有上三角矩阵和下三角矩阵两种。

    上三角矩阵的特点是对角线下方(不包括主对角线)的元素均为常数C。

    下三角矩阵的特点是对角线上方(不包括主对角线)的元素均为常数C。

    三角矩阵与对称矩阵的压缩存储类似,对于上三角矩阵而言,应先存储完对角线上方的元素后,再存储对角线下方常量,因为是同一个常量,只需划分一个存储空间。

    • 对角矩阵

    所有非零元素集中在主对角线为中心的带状区域

    除第0行和第n-1行是两个元素外,其他每行均为3个非零元素,因此需要存储的元素个数为2+2+3{n-2}=3n-2。将其压缩存储在B数组中,

    由于这些特殊的矩阵元素有着一定的规律,在存储的时候为了节省存储空间,可以对这些矩阵进行压缩存储。所谓压缩存储就是为多个值相同的元素分配一个存储空间,对零元素不分配存储空间。

    分析:

    数组本身是线性表的推广,一维数组是一个向量形式的线性表,二维数组是一维数组组成的线性表。关于矩阵,它在科学计算领域等应用中,经常用到矩阵的概念,具有元素数目固定以及按下标关系有序排列等特点。基于压缩存储思想,矩阵中的相同数据元素(包括元素0)只存储一个。

    展开全文
  • 前言随着年龄增长,公事增多,知识面增加,对许多除了用还要记的技术要点,忘的比快,所以需要对大脑内存进行压缩,这篇写给自己,自己常看常更常新。此文想要做,就是通过最简短语言来或概括或描述或引申...

    b4d5e6ac1a5fe24eec2b21cbc367188b.png

    前言

    随着年龄增长,公事增多,知识面增加,对许多除了用还要记的技术要点,忘的比记的快,所以需要对大脑内存进行压缩,这篇写给自己,自己常看常更常新。

    此文想要做的,就是通过最简短的语言来或概括或描述或引申一些较为常用的JS技术,本想都限制在一句,但对于技术来讲,内容远比形式重要的多,尽量吧。

    由于尽量概况,此文的描述或定义都是较为片面与有失偏颇的,甚至是偏激的,但对于写给自己来说,应该采用最大收益——涵盖80%的应用场景即可。

    Module

    Module,模块化,化整为零,为重用;命名空间,为作用域。相关技术及模块规范有CommonJS、AMD、UMD、CMD、SystemJS、ES6 Module等等,此处为学习与收益最大化,略去UMD、CMD、SystemJS。

    CommonJS——是规范,NodeJS为其实现,模块化的先驱,由于同步加载,故用于服务端,核心为require函数及module.exports。

    AMD——是规范,require.js/dojo为其两实现,针对同步加载,故是晚于CommonJS,多用于前端,核心define及require两API。学习其收益不大,也可弃之,唯ArcGIS JS API抱着dojo大腿不放,再不放一起沉沦。

    ES6 Module——是规范,各大浏览器的JS引擎为其实现,后浪推前浪,多用于前端,核心import与export,静态编译时加载,主要学习对象。

    总结一表:

    c081839bca291ff14b8ef810d783fdd5.png

    CommonJS的简单模拟

    模拟分两步:

    1.基本逻辑流程

    2.部分流程细化(伪代码)

    3.前端模拟类似CommonJS与AMD的混合体

    一、基本逻辑流程

    本段参考,也可移步下面文章:

    Starkwang:手写一个CommonJS打包工具(一)zhuanlan.zhihu.com
    cd444b6745e832db3172e442c0a6ac50.png

    1.模拟require主逻辑

    2.忽略模块路径解析

    3.忽略加载模块及执行模块(Node采用VM)

    模拟代码:

    //模拟commonjs同步加载module js文件,并执行。
    modules = {
        //point模块
        "point": function(module, exports, require) {
            function Point(x, y) {
                this.x = x;
                this.y = y;
            };
            Point.prototype.toString = function() {
                return this.x + "," + this.y;
            };
            module.exports = Point;
        },
        //polygon模块
        "polygon":  function(module, exports, require) {
            var Point = require("point");
            function Polygon(center) {
                this.center = center;
            };
            Polygon.prototype.toString = function() {
                return "Center: " + this.center.toString();
            };
            module.exports = Polygon;
        },
        //shape模块
        "shape":  function(module, exports, require) {
            var Point = require("point");
            var Polygon = require("polygon");
            var pt = new Point(1, 1);
            var pg = new Polygon(pt);
            exports.log = pg.toString();
        }
    };
    
    //加载模块缓存
    cache = {};
    
    //require主逻辑
    function require(id) {
        if (cache[id]) {
            //有缓存
            return cache[id].exports;
        } else {
            //无缓存,新建模块
            var module = {
                id: id,
                exports: {},
                loaded: false,
            };
            //执行模块
            modules[id].call(module.exports, module, module.exports, require);
            module.loaded = true;
            //缓存模块
            cache[id] = module;
            return module.exports;
        }
    };

    应用代码:

    var shape = require('c-shape');
    console.log(shape.log);

    二、部分流程细化(伪代码)

    1.伪代码细化加载模块及执行模块

    2.忽略json文件及node二进制文件,只考虑js文件

    伪代码:

    //伪代码
    
    //解析路径
    function parse(id) {
        var url;
        //根据require(id),来解析模块的具体路径
        return url;
    }
    
    //加载模块文件
    function load(url) {
        //伪代码, fs.readFile
        var script;
        return script;
    }
    
    //模块加首尾包装
    function wrap(script) {
        var prefix = "function(module, exports, require) {";
        var suffix = "}";
        return prefix + script + suffix;
    }
    
    
    //加载模块缓存
    cache = {};
    
    //require主逻辑
    function require(id) {
        if (cache[id]) {
            //有缓存
            return cache[id].exports;
        } else {
            //无缓存,新建模块
            var module = {
                id: id,
                exports: {},
                loaded: false,
            };
    
            //伪代码start
            //解析路径
            var url = parse(id);
            //加载模块文件
            var script = load(url);
            //模块加首尾包装
            script = wrap(script);
            //执行模块 node: vm.runInThisContext, 此处用eval()代替
            var run = eval(script);
            run.call(module.exports, module, module.exports, require);
            //伪代码end
            
            module.loaded = true;
            //缓存模块
            cache[id] = module;
            return module.exports;
        }
    };
    
    

    三、CommonJS与AMD的混合体

    结合上一小节,由于模块加载是同步进行,故在服务端较为适合,node采用内置模块fs.readFile,如果放到前端来模拟,很容易想到通过ajax来获取模块(类似CommonJS与AMD的混合体)。思路如下:

    模拟代码

    //解析路径,只考虑js文件
    function parse(id) {
        var url = id;
        //根据require(id),来解析模块的具体路径
        return url;
    }
    
    //加载模块文件
    function load(url) {
        return new Promise((resolve, reject) => {
            $.get(url).done( (data) => {
                resolve(data);
            })
            .fail( (error) => {
                reject(error);
            });
        });
    }
    
    //模块加首尾包装
    function wrap(script) {
        var prefix = "async function exec(module, exports, require) {";
        var suffix = "}";
        return prefix + script + suffix;
    }
    
    
    //加载模块缓存
    cache = {};
    var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
    //require主逻辑
    async function require(id) {
        if (cache[id]) {
            //有缓存
            return cache[id].exports;
        } else {
            //无缓存,新建模块
            var module = {
                id: id,
                exports: {},
                loaded: false,
            };
    
            //解析路径
            var url = parse(id);
            //加载模块文件
            var script = await load(url);
            //模块加首尾包装
            //script = wrap(script);
            //执行模块 node: vm.runInThisContext, 此处用new Function代替
            var run = new AsyncFunction("module", "exports", "require", script);
            await run(module, module.exports, require);
    
            module.loaded = true;
            //缓存模块
            cache[id] = module;
            return module.exports;
        }
    };

    应用代码

    //.point.js
    function Point(x, y) {
        this.x = x;
        this.y = y;
    };
    Point.prototype.toString = function() {
        return this.x + "," + this.y;
    };
    module.exports = Point;
    
    //.polygon.js
    var Point = await require("./point.js");
    function Polygon(center) {
        this.center = center;
    };
    Polygon.prototype.toString = function() {
        return "Center: " + this.center.toString();
    };
    module.exports = Polygon;
    
    //.shape.js
    var Point = await require("./point.js");
    var Polygon = await require("./polygon.js");
    var pt = new Point(1, 1);
    var pg = new Polygon(pt);
    exports.log = pg.toString();
    
    //index.html
        <script type="text/javascript">
            async function init() {
                var shape = await require('./shape.js');
                document.getElementById("log").value = shape.log;
            }
        </script>
    补充
    很多人搞不清,module.exports与exports的区别,如上代码,交代的非常清楚,首先module.exports是一个对象,第二module.exports作为传入参数——实参,exports是形参,所以,在模块内部,不能exports = something(这样后果是module.exports还是默认对象),而是exports.something = something, 或者module.exports = something。
    展开全文
  • 前言随着年龄增长,公事增多,知识面增加,对许多除了用还要记的技术要点,忘的比快,所以需要对大脑内存进行压缩,这篇写给自己,自己常看常更常新。此文想要做,就是通过最简短语言来或概括或描述或引申...

    f92a68aee1311783c3ece894715923e7.png

    前言

    随着年龄增长,公事增多,知识面增加,对许多除了用还要记的技术要点,忘的比记的快,所以需要对大脑内存进行压缩,这篇写给自己,自己常看常更常新。

    此文想要做的,就是通过最简短的语言来或概括或描述或引申一些较为常用的JS技术,本想都限制在一句,但对于技术来讲,内容远比形式重要的多,尽量吧。

    由于尽量概况,此文的描述或定义都是较为片面与有失偏颇的,甚至是偏激的,但对于写给自己来说,应该采用最大收益——涵盖80%的应用场景即可。

    Module

    Module,模块化,化整为零,为重用;命名空间,为作用域。相关技术及模块规范有CommonJS、AMD、UMD、CMD、SystemJS、ES6 Module等等,此处为学习与收益最大化,略去UMD、CMD、SystemJS。

    CommonJS——是规范,NodeJS为其实现,模块化的先驱,由于同步加载,故用于服务端,核心为require函数及module.exports。

    AMD——是规范,require.js/dojo为其两实现,针对同步加载,故是晚于CommonJS,多用于前端,核心define及require两API。学习其收益不大,也可弃之,唯ArcGIS JS API抱着dojo大腿不放,再不放一起沉沦。

    ES6 Module——是规范,各大浏览器的JS引擎为其实现,后浪推前浪,多用于前端,核心import与export,静态编译时加载,主要学习对象。

    总结一表:

    8dec69f3d83016224d0656b16d7dcd9f.png

    CommonJS的简单模拟

    模拟分两步:

    1.基本逻辑流程

    2.部分流程细化(伪代码)

    3.前端模拟类似CommonJS与AMD的混合体

    一、基本逻辑流程

    本段参考,也可移步下面文章:

    Starkwang:手写一个CommonJS打包工具(一)zhuanlan.zhihu.com
    95345c9368cbf23897959b2d491027bd.png

    1.模拟require主逻辑

    2.忽略模块路径解析

    3.忽略加载模块及执行模块(Node采用VM)

    模拟代码:

    //模拟commonjs同步加载module js文件,并执行。
    modules = {
        //point模块
        "point": function(module, exports, require) {
            function Point(x, y) {
                this.x = x;
                this.y = y;
            };
            Point.prototype.toString = function() {
                return this.x + "," + this.y;
            };
            module.exports = Point;
        },
        //polygon模块
        "polygon":  function(module, exports, require) {
            var Point = require("point");
            function Polygon(center) {
                this.center = center;
            };
            Polygon.prototype.toString = function() {
                return "Center: " + this.center.toString();
            };
            module.exports = Polygon;
        },
        //shape模块
        "shape":  function(module, exports, require) {
            var Point = require("point");
            var Polygon = require("polygon");
            var pt = new Point(1, 1);
            var pg = new Polygon(pt);
            exports.log = pg.toString();
        }
    };
    
    //加载模块缓存
    cache = {};
    
    //require主逻辑
    function require(id) {
        if (cache[id]) {
            //有缓存
            return cache[id].exports;
        } else {
            //无缓存,新建模块
            var module = {
                id: id,
                exports: {},
                loaded: false,
            };
            //执行模块
            modules[id].call(module.exports, module, module.exports, require);
            module.loaded = true;
            //缓存模块
            cache[id] = module;
            return module.exports;
        }
    };

    应用代码:

    var shape = require('c-shape');
    console.log(shape.log);

    二、部分流程细化(伪代码)

    1.伪代码细化加载模块及执行模块

    2.忽略json文件及node二进制文件,只考虑js文件

    伪代码:

    //伪代码
    
    //解析路径
    function parse(id) {
        var url;
        //根据require(id),来解析模块的具体路径
        return url;
    }
    
    //加载模块文件
    function load(url) {
        //伪代码, fs.readFile
        var script;
        return script;
    }
    
    //模块加首尾包装
    function wrap(script) {
        var prefix = "function(module, exports, require) {";
        var suffix = "}";
        return prefix + script + suffix;
    }
    
    
    //加载模块缓存
    cache = {};
    
    //require主逻辑
    function require(id) {
        if (cache[id]) {
            //有缓存
            return cache[id].exports;
        } else {
            //无缓存,新建模块
            var module = {
                id: id,
                exports: {},
                loaded: false,
            };
    
            //伪代码start
            //解析路径
            var url = parse(id);
            //加载模块文件
            var script = load(url);
            //模块加首尾包装
            script = wrap(script);
            //执行模块 node: vm.runInThisContext, 此处用eval()代替
            var run = eval(script);
            run.call(module.exports, module, module.exports, require);
            //伪代码end
            
            module.loaded = true;
            //缓存模块
            cache[id] = module;
            return module.exports;
        }
    };
    
    

    三、CommonJS与AMD的混合体

    结合上一小节,由于模块加载是同步进行,故在服务端较为适合,node采用内置模块fs.readFile,如果放到前端来模拟,很容易想到通过ajax来获取模块(类似CommonJS与AMD的混合体)。思路如下:

    模拟代码

    //解析路径,只考虑js文件
    function parse(id) {
        var url = id;
        //根据require(id),来解析模块的具体路径
        return url;
    }
    
    //加载模块文件
    function load(url) {
        return new Promise((resolve, reject) => {
            $.get(url).done( (data) => {
                resolve(data);
            })
            .fail( (error) => {
                reject(error);
            });
        });
    }
    
    //模块加首尾包装
    function wrap(script) {
        var prefix = "async function exec(module, exports, require) {";
        var suffix = "}";
        return prefix + script + suffix;
    }
    
    
    //加载模块缓存
    cache = {};
    var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
    //require主逻辑
    async function require(id) {
        if (cache[id]) {
            //有缓存
            return cache[id].exports;
        } else {
            //无缓存,新建模块
            var module = {
                id: id,
                exports: {},
                loaded: false,
            };
    
            //解析路径
            var url = parse(id);
            //加载模块文件
            var script = await load(url);
            //模块加首尾包装
            //script = wrap(script);
            //执行模块 node: vm.runInThisContext, 此处用new Function代替
            var run = new AsyncFunction("module", "exports", "require", script);
            await run(module, module.exports, require);
    
            module.loaded = true;
            //缓存模块
            cache[id] = module;
            return module.exports;
        }
    };

    应用代码

    //.point.js
    function Point(x, y) {
        this.x = x;
        this.y = y;
    };
    Point.prototype.toString = function() {
        return this.x + "," + this.y;
    };
    module.exports = Point;
    
    //.polygon.js
    var Point = await require("./point.js");
    function Polygon(center) {
        this.center = center;
    };
    Polygon.prototype.toString = function() {
        return "Center: " + this.center.toString();
    };
    module.exports = Polygon;
    
    //.shape.js
    var Point = await require("./point.js");
    var Polygon = await require("./polygon.js");
    var pt = new Point(1, 1);
    var pg = new Polygon(pt);
    exports.log = pg.toString();
    
    //index.html
        <script type="text/javascript">
            async function init() {
                var shape = await require('./shape.js');
                document.getElementById("log").value = shape.log;
            }
        </script>
    补充
    很多人搞不清,module.exports与exports的区别,如上代码,交代的非常清楚,首先module.exports是一个对象,第二module.exports作为传入参数——实参,exports是形参,所以,在模块内部,不能exports = something(这样后果是module.exports还是默认对象),而是exports.something = something, 或者module.exports = something。
    展开全文
  • 就又加剧了前端技术的多元化和去中心化的大趋势。所以我们经常开玩笑,百度的前端业务得多简单,一个 <a href="http://fis.baidu.com/">FIS</a> 就可以支撑百度绝大多数前端业务了。 所以,问题很...
  • 简析H.264芯片与技术

    2013-03-05 14:08:10
    H.264 是MPEG-4标准所定义的最新格式,代表最新技术水平的视频编码格式之一,有的也称AVC...H.264最大的优势是具有很高的数据压缩比率,在同等图像质量的条件下,H.264的压缩比是MPEG-2的2倍以上,是MPEG-4的1.5~2倍。
  • 摘要:概述了JPEG2000标准PART1基本系统,介绍了其重要特点:感兴趣区域编码;介绍了一种新ROI编码算法——...(1)良好低比特率压缩性能,其压缩JPEG高约30%左右; (2)支持无损和有损压缩; (3)按
  • 目前,在煤矿使用模拟视频信号煤矿工业电视监控系统已经不能满足煤矿综合自动化的技术发展,新型视频监控系统应在确保视频采集和压缩的实时性同时,支持视频流在工业以太网上IP传输,实现全矿信息化数字化...
  • 定义上来说,多文档摘要就是将同一主题下多个文本描述主要信息按压缩比提炼出一个文本自然语言处理技术。从应用上来说,一方面,在互联网上使用搜索引擎时候,搜索同一主题文档往往会返回成千上万网页,...
  • 脉冲压缩技术用能量累计技术,使得接收回波经过处理后脉宽发射脉冲大大减小。在脉冲压缩中经常使用是线性调频脉冲信号。 2 线性调频脉冲信号定义 瞬时频率线性增加线性调频脉冲波形复包络为: x~(t)=a(t...
  • 5.1.2 压缩比 5.1.3 主观评价方法 5.2 不同类型小波基压缩效果分析 5.2.1 SST图像压缩结果 5.2.2 SST图像压缩后质量分析 5.2.3 SST图像压缩后主观质量评价 5.3 小波分解层次影响 5.4 采用阈值处理方法图像...
  • 分别从两个不同角度提出了新适合图像载体掩密安全性定义:基于可逆去相关变换相对熵安全性定义和基于Markov图像模型条件相对熵安全性定义,并分别以不同图像模型对这两个定义进行了讨论。所提安全性定义...
  • 下面是二系列内容中第一部分,第一部分我们...一旦有人了解并使用了css技术,没有多少人认为对网站布局和定义用css会用table表格有难度。然而,对于管理大型动态、复杂网站样式明显是一个艰巨工作。 禁止压缩
  • 早在上世纪80年代,随着科学技术的不断发展,SDI得到了快速发展并对其标准作出了定义。SDI是串行数字接口,被用来传送无压缩的数字视频信号。3G-SDI中的3G是指SDI信号的数据传输率为3Gbit每秒。由于HDTV可以支持每秒...
  • 早在上世纪80年代,随着科学技术的不断发展,SDI得到了快速发展并对其标准作出了定义。SDI是串行数字接口,被用来传送无压缩的数字视频信号。3G-SDI中的3G是指SDI信号的数据传输率为3Gbit每秒。由于HDTV可以支持每秒...
  • WebAssembly是此应用程序不错选择,因为编译后RustJavascript快得多,并且计算需要快速完成。 支持开发环境 该项目所有开发均在Windows计算机上以VS Code完成。 但是,Rust WebAssembly仅在Linux Ubuntu...
  • 6.5.3 几类小区的定义 361 6.5.4 信令无线承载(SRB) 361 6.5.5 消息列表 361 参考文献 363 第7章 第三代移动通信核心网络演进(EPC) 365 7.1 架构参考模型和接口协议 366 7.1.1 非漫游架构 ...
  • boost库----->dynamic_bitset学习

    千次阅读 2016-06-09 11:29:14
     vector是对元素类型为bool的vector特化,它的内部并不真正存储bool值,而是以bit来压缩保存、使用代理技术来操作bit,造成的后果就是它很像容器,大多数情况下和标准容器一致,但它不是容器,不满足容器的定义。...
  • CISCO 技术大集合

    2013-05-22 01:07:13
    CISCO 技术大集合 {适合你们的技术} 二、命令状态 1. router> 路由器处于用户命令状态,这时用户可以看路由器连接状态,访问其它网络和主机,但不能看到和更改路由器设置内容。 2. router# 在router>提示符...
  • 6.5.3 几类小区的定义 361 6.5.4 信令无线承载(SRB) 361 6.5.5 消息列表 361 参考文献 363 第7章 第三代移动通信核心网络演进(EPC) 365 7.1 架构参考模型和接口协议 366 7.1.1 非漫游架构 ...
  •  MOU是WinMount定义的压缩标准。MOU文件压缩比高,压缩时间短,能瞬时被打开,不解压,直接使用。  WinMount提供转换功能,可将RAR、ZIP、7Z文件转换为MOU.  7.WinMount硬盘格式WMT  支持创建WMT,并将文件存储...
  • 6.5.3 几类小区的定义 361 6.5.4 信令无线承载(SRB) 361 6.5.5 消息列表 361 参考文献 363 第7章 第三代移动通信核心网络演进(EPC) 365 7.1 架构参考模型和接口协议 366 7.1.1 非漫游架构 366 ...
  • 在一些情况下分形压缩可以达到非常高的压缩比,因此这是一种极具发展潜力的图像压缩技术。分形图像压缩的概念首先由Barnsley提出,但是Barnsely基于IFS的分形压缩方法在实话时需要人机交互,无法实现自动化的压缩...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 143
精华内容 57
关键字:

压缩技术的压缩比的定义