总第篇
年第篇
设计稿(UI视图)转代码是前端工程师日常不断重复的工作,这部分工作复杂度较低但工作占比较高,所以提升设计稿转代码的效率一直是前端工程师追求的方向之一。此前,前端工程师尝试过将业务组件模块化构建成通用视图库,并通过拖拽、拼接等形式搭建业务模块,从而实现视图复用,降低设计稿转代码的研发成本。但随着业务的发展和个性化的驱动,通用视图库无法覆盖所有应用场景,本文提出了一种设计稿自动生成代码的方案。1背景设计稿(UI视图)转代码是前端工程师日常不断重复的工作,这部分工作复杂度较低但工作占比较高,所以提升设计稿转代码的效率一直是前端工程师追求的方向之一。此前,前端工程师尝试过将业务组件模块化构建成通用视图库,并通过拖拽、拼接等形式搭建业务模块,从而实现视图复用,降低设计稿转代码的研发成本。但随着业务的发展和个性化的驱动,通用视图库无法覆盖所有应用场景,本文提出了一种设计稿自动生成代码的方案。
目前,业内主流的代码生成方案有两种,一种是通过训练神经网络,从图片或草图直接生成代码,以微软sketch2json为代表;另一种是基于Sketch源文件,从中解析出图层信息转化成DSL并生成代码,以imgCook为代表。
经过实践,我们发现第一种方案基于神经网络的代码生成算法虽然简单粗暴,但复杂层布局的准确率较低、可解释程度不高导致后续无法持续优化。方案二中Sketch源文件信息量丰富、算法自定义程度高、优化空间大。因此,我们调研了业界基于Sketch的代码自动生成方案(已对外公布或者开源),发现了一些不足并尝试解决,下面从算法准确率、代码可读性、研发流程覆盖度等方面做一下对比(该对比结果仅考察业界方案对我们自己业务的适用性,实际结果可能存在差异):
算法准确率方面:淘宝imgCook支持基于AI的组件识别,不支持成组布局,准确率中等(从1.1递归介绍
递归是一种编程技巧,一种解决问题的思维方式;严格来说,递归并不是一种算法。简单地说,就是如果在函数中存在着调用函数本身的情况,这种现象就叫递归。
递归的思想就是,将大问题分解为小问题来求解,然后再将小问题分解为更小的问题。这样一层一层地分解,直到问题规模分解得足够小,不用继续分解,可以直接计算结果为止。
如果把这个一层一层分解过程画成图,可以类比为一颗树。这颗树可以起一个名字,叫做:递归树,以斐波那契数列为例:
publicclassSolution{publicintfib(intn){if(n=1){turnn;}turnfib(n-1)+fib(n-2);}}
递归树如下图所示:
递归法:
递归再“归”的过程中,符合后进先出得规则,所以需要一个堆栈的数据结构,递归过程中函数调用会自动产生一个栈帧,当函数帧栈的深度越来越大的时候,栈也越来越大,如果递归没有终止条件,就会出现栈的溢出。所有基于递归的思想实现的算法,第一步要思考的就是递归的终止条件。
分治算法和动态规划很大程度上是递归思想上的一种解决更具体问题的两类算法思想。
进一步剖析递归,先有递,再有归,递的意思是将问题拆解成子问题来解决。子问题再拆解成子问题,.........直到被拆解的问题无需再拆分成更细的子问题(即可以求解),归是说最小的子问题解决了,那么它的上一层子问题就解决了,上一层的子问题解决了,上上层的子问题自然也就解决了。
递归的一般结构:
voidfunc(){if(符合边界条件){//////turn;}//某种形式的调用func()}
以阶层函数为例,如下,在factorial函数中存在着factorial(n-1)的调用,所以此函数是递归函数:
publicintfactorial(intn){if(n=1){turn1;}turnn*factorial(n-1)}
以阶层f(6)为例来看下它的「递」和「归」
求解问题f(6),由于f(6)=n*f(5),所以f(6)需要拆解成f(5)子问题进行求解,同理f(5)=n*f(4),也需要进一步拆分,...,直到f(1),这是「递」,f(1)解决了,由于f(2)=2f(1)=2也解决了,....f(n)到最后也解决了,这是「归」,所以递归的本质是能把问题拆分成具有相同解决思路的子问题,。。。直到最后被拆解的子问题再也不能拆分,解决了最小粒度可求解的子问题后,在「归」的过程中自然顺其自然地解决了最开始的问题。
1.2基本步骤
(1)定义一个函数,明确函数的功能。
(2)寻求问题与子问题之间的关系(递归公式)
(3)将递归公式再定义的函数中实现
(4)推导时间复杂度,判定是否可以接受,无法接受更换算法。
1.3代表题目
1.3.爬楼梯