APP下载

结构性文档下基于MCPS2的意图维护与undo算法研究

2021-11-22朱思征王山山高丽萍

小型微型计算机系统 2021年11期
关键词:副本复杂度文档

王 丹,朱思征,王山山,高丽萍

1(上海理工大学 计算中心,上海 200093)

2(上海理工大学 光电信息与计算机工程学院,上海 200093)

1 引 言

CSCW[1](计算机支持的协同工作:Computer Supported Cooperative Work)作为一种新的工作模式,于1989年提出,历经30余年的研究,研发了大量的协同编辑算法[2-4]与协同应用或系统[5-8],为团队协作的技术发展做出了巨大贡献.但传统的乐观协同控制算法,多是解决多用户桌面协同操作的并发冲突问题,在移动互联网迅速发展、移动设备与技术快速迭代的当今社会,考虑到工作的即时性与便利性需求,桌面协同已无法满足日渐提高的用户需求.因此,科研人员围绕移动互联网、云计算、云平台展开了一系列算法基础[9-12]与移动应用[13-15]研究.

移动端协同领域研究主要解决的问题即如何在面临动态网络、资源限制、算法效率、文档模型等各种约束条件下,基于传统的乐观控制算法,设计和重构适用于移动终端的并发控制算法,实现在最大程度上满足多用户意愿的同时,保证用户操作端文档的一致性,最终研发适配度高,响应性快的移动协同应用.

考虑到移动端在计算能力与存储能力方面的限制,我们将协同操作的文档模型聚焦在结构文档(文档的内容间具有清晰明确的等级关系或层次结构)[16]上.首先结构文档在各行各业都具备很高的实用性,例如投标书、科研文章、专利申请书等有指定格式与结构要求的文本类文档,html文档、思维导图等具有严格层级关系的专业性文档;其次,文本协同编辑领域的乐观控制算法研究相对成熟,有强大的理论知识后盾,在之前的研究[16,17]中,通过活跃度计算与判定的冲突消解机制,权限分配与转移的意图维护手段,在一定程度上满足了多用户意愿的同时维护协作副本的一致性;最后,结构性文档的抽象化存储方式,更适用于存储能力有限的移动终端.

为了进一步的完善移动终端下的结构文档协同编辑算法的完整性、合理性和高效性,我们在MCPS2算法基础上改善了操作权限的配置方式,参考文献[18,19]中支持Undo/Redo操作的设计思想增加了 “撤销”操作类型,并在操作执行方面做出了调整.本文的结构如下:首先回顾MCPS2算法的执行流程与并发控制方法,并给出本文算法中涉及的文档结构、节点类型及属性、操作类型与权限的基本定义;然后对改进算法进行详细描述;并分析主体算法的复杂度,并结合实例阐述算法的整体执行流程,验证其有效性;最后给出总结,介绍今后的研究方向和重点.

2 相关工作

1998年Sun[20]在Eliis[1]人提出的CCI(Convergence Causality Intention)一致性模型基础上加入意愿维护的标准,其中一致性维护是验证算法的准确性,而意愿维护的程度是评判算法应用性的重要标准.在一致性维护方面,目前乐观算法大多基于OT[1](Operation Trans-formation)与AST[21](Address Space Transformation),例如CSOT[11](Cloud Storage Operational Transformation)云存储操作转换函数,能够支持云存储下文件粒度的实时一致性同步,COT[2]基于上下文的操作转换算法等.基于这些算法,研发了一系列处理文本、图像、代码的协作应用和系统,比如Google Docs(1)Google Docs[EB/OL].http://docs.google.com/,2015.、Microsoft Office 365(2)Microsoft Office 365[EB/OL].https://office.live.com/,2016.等支持文档的协同编辑系统,Cloud9 IDE(3)Cloud9 IDE[EB/OL].https://c9.io/,2016.、CoRED[22]等支持java程序协同开发的工具,ProcessOn、SketchPad、CSCW-based CAD[4]等支持在线协同绘图服务的平台.意图维护方面,WH Wang[13]等人利用3种共享锁机制解决语义冲突实现协同编程,Sun[23]等人提出基于 OT 技术采用多版本技术解决 2D 文档模型下垂直交叉的冲突,维护了 2D 文档一致性.以上算法多是在存储空间、网络状态良好的乐观前提下执行,当前移动网络与移动设备发展迅速,将乐观协同算法适当改良和优化移植到移动端,势在必行.

目前基于移动网络研发了部分算法[3,9,14]与应用[12,15],其中首要解决的是移动网络不稳定的问题.就此问题,Shao等人提出支持异步协同的算法ABST[3],解决了网络断联后如何处理各协作站点产生的操作集合.L Gao[24]等人发现ABST的成功执行需要必要前提,并研究提出能够构造此前提的一致性维护算法,即支持操作续传的网络3阶段一致性维护算法.其次是解决存储空间和计算能力有限的问题,目前乐观算法多用使用全复制式架构[1,2](full replication architecture),优点是本地响应速度快,缺点是浪费带宽资源,占用本地存储.2016年Huan Huanxia[10]等人提出局部复制式架构(Partial replication based on dependency),节约了本地副本存储空间的同时节省了副本更新时间,更适合在移动端使用.基于局部复制原理,我们在之前的文章中提出了适用于移动终端的支持结构文档操作的MCPS[16]与MCPS2[17]算法,提出了副本监听、活跃度、创始站点等定义,尽可能上满足多用户的操作意愿的同时,设计冲突消解算法实现一致性维护的目的.出于功能性与应用性的考虑,本文基于MCPS2算法,新增了支持Undo操作的处理进程,同时改良了删除机制,利用预设权限提升了协作效率.

3 准备工作

3.1 MCPS2算法回顾

如图1中的标题结构文档,假设此时有3个用户Site0、Site1和Site2同时编辑此文档,用户创建的节点序列如下:

图1 MCPS2 算法举例

Site0:TC=[DOC]

Site1:TC=[A,A1,B1,B2]

Site2:TC=[B,A2,A21,A22,A23]

由于Site0发起了此次协同编辑事件,则DOC.master=Site0,为了清晰描述MCPS2中的核心算法,我们假设3个用户仅执行了标题插入操作,其他标题的编辑、删除与内容的编辑操作均不涉及,那么此时标题节点B的属性是:

B={2,2,DOC,[B1,B2],data,name,TN,1,[0,0,1],[0,2,1],2,null},其中[0,0,1]代表各协作站点在该节点的节点活跃度(NLV),表示site2创建节点B,site0和site1没有对B执行任何操作;[0,2,1]代表各协作站点在节点的树活跃度(TLV),即各用户在以B为根节点的树中的所有节点执行操作的活跃度总和.

1)活跃度对比解决操作冲突举例

假设此时协作站点发起两个操作:

site0:InsertTitle(B,B3,0,data,name)

site1:InsertTitle(B,B3,0,data,name)

首先插入节点为一级标题B节点的子节点,两站点需要先向B节点的TC即site2发起编辑请求,假设site2同意两站点执行此操作,但是此时发生了插入位置冲突,根据MCPS2算法,此时先比较两站点在B节点的节点活跃度NLV,因为(B.NLV.site0==0)=(B.NLV.site1==0),继续比较两站点在B节点的树活跃度TLV,(B.TLV.site0==0)<(B.TLV.site1==2),所以site1插入操作优先于site0执行,冲突消解后,site0的插入操作调整为:

site0:InsertTitle(B,B4,0,data,name)

2)master权限转移

当前master为site0,若site0退出协同编辑,触发master权限转移机制,系统会自动计算各站点在DOC节点的树活跃度,活跃度最高站点将继承master,同时广播至所有站点,将原master站点创建的节点TC之修改为新master站点,具体操作如下:

(DOC.TLV.site1==4)<(DOC.TLV.site2==5)

master → site2

master.TCListappend to site2

最后site2.TC=[DOC,B,A2,A21,A22,A23].

MCPS2在活跃度的比对与一致性维护方面已经相对完善,但在master转移和节点权限请求效率方面有待于优化,并且在结构文档的协同编辑下,有必要根据实际应用性调整已有操作的执行方法,同时加入Undo功能,本文算法针对以上几方面给出解决方案,以下为本文涉及的几个关键基本定义.

3.2 文档定义

文档结构与存储结构如图1所示,继续沿用MCPS2算法中的定义与解析方法,主副本利用树形结构存储,树中的子父级关系代表标题节点的层级,这里不做赘述.

3.3 节点类型定义

在MCPS和MCPS2以及更早的基于局部复制策略的算法中,大多将节点类型分为请求节点、结构父节点和结构兄弟节点,在MCPS2算法中,我们将节点分为两大类[参考文献],包括标题节点(TN:Title-Node)、结构父节点(SPN:Str-Parent-Node)和结构兄弟节点(SBN:Str-Brother-Node)的第1类现实节点;同时提出虚拟标题节点(VTN:Virtual-Title-Node)第2类虚拟节点,为维护结构文档整体树型结构和本文提出的undo操作和delete的改进操作执行而存在.具体的节点使用将在下文中详解.

3.4 节点属性定义

本文提出的算法在MCPS2基本操作上提出了Undo操作,因此在节点属性定义中新增Undo操作的历史序列UHB(Undo History Buffer),以及节点操作权限标记PM,为了更好地区分节点定义中属性的主要功能,我们给出图2中的节点属性定义划分,其中:

图2 节点属性定义

1)基础属性:记录了标题节点的名称和内容,决定了标题在结构文档中的层级和位置;

2)数据同步:type和value两个属性主要用于协作站点请求数据时,局部复制后保证文档树结构的完整性;

3)冲突消解:对于协作站点发起的操作,一旦产生位置或更新等冲突,此时需要对比操作对象上执行站点间的节点活跃度NLV或树活跃度TLV,调整操作的执行顺序或具体属性,保证最大程度上满足各协作用户的意愿;

4)操作权限:节点的创造者与协作用户群,是决定在某节点某协作用户是否具备编辑或删除权限的主要因素,PM标记类型参照文中权限定义部分;

5)UHB(Undo History Buffer):是记录master未发起文档合并命令前本地执行的历史操作序列,以执行本地的撤销操作.

3.5 操作定义

在之前的Delete操作中,一旦删除某标题节点,以该节点为根节点的所有节点将被删除,为了提升应用性,我们对Delete操作进行改进:“删除标题节点操作仅删除该节点本身,不删除其子孙节点”.另外引入undo操作,支持用户在未响应文档合并命令前撤销已执行的操作.在表1中,我们给出本算法涉及的主要操作,以及执行undo后对应的操作,具体操作流程在本文第4部分详细描述.

表1 操作类型和说明

3.6 权限定义

在之前的MCPS2算法中,只有在其它协作站点请求节点数据的时候,才能通过TC节点和其他CE节点的仲裁结果决定是否可以操作此节点,如图3所示,在request user发出请求后需要等待TC user决定是否接受请求,通过后CE users并发投票(赞成数大于等于反对接受同步请求,否则不接受),最后将请求结果返回给request user.考虑到请求的反馈速度与TC和CE站点操作执行的连贯性与执行效率,我们为文档中的节点引入权限概念,TC站点可以在创建节点或编辑过程中为标题节点赋予权限,优化请求站点发送请求操作到接收执行的中间过程,减少等待阶段与时间.本算法的节点操作权限主要分为以下几种:

图3 MCPS2中的Arbitration算法

1)Edit:协作站点可以直接请求并编辑节点,但不可删除节点;

2)Readonly:协作站点可以请求同步节点,但只能查看节点内容,不可编辑;

3)Delete:非TC的协作站点可以请求编辑或删除节点;

4)Locked:CE用户总数超过系统默认最大协同用户量或TC设置的最大协同用户量时Edit权限自动锁定,转为Readonly;

5)Arbitrated:默认权限,在TC站点未赋予节点任何权限时使用,与MCPS2中的请求节点方式相同,需要向TC与CE站点申请编辑权限,具体流程如图3.

4 MCPS2算法改进

4.1 节点权限控制

当第1次创建结构文档、站点新增标题节点或协作用户在协作过程中修改自身创建的节点的权限时时触发此事件.

算法1.ConstructDoc(Doc):Str-Doc

输入:[N]/*节点集*/

输出:Str-Doc

1.Forn 0 to[N].lengthDo

2. n.TC executes PM-control(n of[N],PM)

3. n.PM←PM

4.Ifn is new nodethen/*提升传输效率*/

5. broadcast n to master

6.Else

7. broadcast n.PM to master

8.Endif

9.Endfor

通过权限控制算法,为单个节点赋予操作权限,权限包括文中3.6小节介绍的5种,其中默认权限为Arbitrated,权限间可由节点的TC用户任意转换,详细算法如下:

算法2.PM-Control(n,PM)

1.IfPM==null ‖“Arbitrated”then

2. Waiting for n.TC && n.CE vote

3.Elseif PM==“Locked”then

4. n.TCInputmax length of n.CE

5.ElseifPM==“Readonly”then

6. n.CE.length←0

7.ElseifPM==”Edit”then

8. n.CE cannot delete n

9.ElseifPM==”Delete”then

10. n.CE can edit n

11.Endif

4.2 UHB输入输出

UHB的存储方式类似于HB的存储,区别在于需要区分已广播和未广播操作,存储除Apeend()的其他类型操作,undo操作时按照先入后出的原则,依次转换操作属性恢复操作执行前的文档状态.

算法3.UHB-In(O)

1. Local operation O is executed

2.While(O !=‘Append’)then

3.IfUHB.length < max(UHB.length)then

4. UHB.append(O)

5.Else

6. Remove(UHB[0])

7. Array index of UBH forward 1 step

8. UHB.append(O)

9.Endif

10.Endwhile

算法4.UHB-Out(O)

1.IfO exist in UHBthen

2. id ← O.id

3.IfO==“InsertTitle”‖“InsertTitleBefore”then

4. execute Delete(id,site)

5.Endif

6.IfO==“UpdateName”then

7. oldName ← O.newName

8. newName ← O.oldName

9. execute UpdateName(id,newName,oldName)

10.Endif

11.IfO==“Delete”then

12. execute Undo-Delete(id,site)

13.Endif

14.IfO had been broadcastedthen

15. Broadcast Undo(O)

16.Else

17. Stop Broadcast O

18.Endif

19.Endif

4.3 Delete与Undo-delete的执行

与之前文章不同的是,delete操作执行并不会将删除节点的子孙节点全部删除,而是先隐藏此节点,将子孙节点暂时继承给兄节点,一旦删除操作被撤销,将恢复节点并恢复其子孙节点,否则在合并文档操作执行后,UHB清空,节点永久被删除.

算法5.Delete(id,site)

1.Ifn.children !=nullthen

2. pbro ← n.prev()

3. nbro ← n.next()

4. children ← n.children()

5. parent ← n.parent()

6.Ifpbro !=nullthen

7. pbro.children.Append(children)

8.Elseifpbro==null && nbro !=nullthen

9. Nbro.children.Prepend(children)

10.Else

11. parent.children.Append(children)

12.Endif

13.Endif

14. n.type ← VTN

15. UHB.In(ODelete)

算法6.Undo-Delete(id,site)

1. n.type ← TN

2. recover n.children()

3. n.prev.children.remove(n.children())

4. UHB.In(OInsert)

4.4 undo-insert的执行

插入操作分为InsertTitleBefore和InsertTitle两种,因为undo操作执行的为上一步操作,所有任意的insert操作在执行后,插入的节点都不会存在子孙节点,所以撤销insert操作后本地将执行对应的delete操作,具体流程与算法5一致.

4.5 UHB清空UHB-destroy

一旦任意站点发起文档合并请求,并合并成功,所有协作站点的UHB将被清空,即用户将不可撤回文档合并前执行的所有操作,其中所有delete操作的节点状态将由隐藏转变为彻底删除.

算法7.UHB-destroy()

1.Whileperforming merge()then

2.Forn 0 to UHB.lengthDo

3.IfUHB[n]==‘Delete’then

4. Remove UHB[n].node from Doc

5.Endif

6.Endfor

7. Clear UHB

8.Endwhile

4.6 master转移

MCPS2算法中忽略了多站点文档活跃度相同的情况,在本文中我们对此算法适当改进.与节点编辑权限预设的方法类似,master同样可以设置自己的“继承者”,若无继承的master,则比对请求副本率超过P(自定义)的协作站点的文档操作活跃度;活跃度相同时判定站点是否发起过文档合并请求,若有则请求最近者为master,若没有则比对站点优先级,优先级高者胜任.

算法8.masterTrans()

1.Whilemaster is off-linethen

2.Ifthe successor of master exsitthen

3. master ← successor

4.else

5.forn 0 to sites.lengthdo

6.Ifsites[n].copy.propotion >=Pthen

7. M.Append(site[n])

8.Endif

9.Endfor

10.IfM.length >=1then

11. Mmax ← Max(M.strDoc.TLV)

12.IfMmax.length > 1then

13. Top priority sites of Mmax ← master

14.Else

15. Mmax[0]← master

16.Endif

17.Else

18. Execute masterChange()of MCPS2

19.Endif

20.Endif

21.Endwhile

本文要求副本占比率需超过30%,计算方式如下,假设Siten站点结构文档副本中标题节点总数为TNSum,结构节点总数为SNsum,主副本节点总数为Str-Doc.Nsum,那么副本占比率PSiten为:

PSiten=(TNsum×Pt+SNsum×Ps)÷Str-Doc.Nsum×100%

其中Pt代表标题节点占副本权重,Ps代表结构节点占副本权重(根据实际情况赋值),本算法Pt设定值为0.8,Ps设定值为0.2.

5 复杂度分析

本算法构建结构文档主要分为3种情况:

1)结构文档初始化,与MCPS2相比加入了预设权限的功能,假设初始化涉及的标题节点数量为n,预设权限节点个数为m,且m<=n(站点若无预设操作,权限为默认值),初始化时间复杂度为O(n+m),最坏情况下时间复杂度为O(n);

2)站点新增标题节点,仅涉及单个节点TC、CE与权限赋值操作,所以时间复杂度为O(1);

3)TC站点修改节点权限,每修改一个节点都会触发初始化进程,因此时间复杂度也为O(1).

最后,在提供节点预设权限功能情况下初始化结构文档的综合时间复杂度为O(n),与MCPS2中结构文档初始化相比,时间复杂度不变,功能得到优化.

在MCPS2算法中需要考虑仲裁延迟时间,假设在最差的环境下,达到S个站点协作上限,请求节点操作权限的时间复杂度为O(S),并且存在n.CE.length *delayTimes(delayTimes为可等待请求结果的最大延迟时间)时长的而延迟.本文算法给出节点预设编辑权限后,默认状态下请求方式同MCPS2;非默认状态下,协作站点在请求节点时无需向TC站点发出任何请求,仅根据该节点已设置的权限查看或操作节点,因此不存在等待延迟,同时优化了时间复杂度为O(1).

本文中对master转移操作流程进行的优化,加入了继承master,同时在master选取上优先考虑请求副本率与请求合并文档时间点,替代原有仅考虑站点活跃度的选取规则.MCPS2中master转移的复杂度取决于协作站点个数T,为O(T),本算法中在设置继承master时时间复杂度为最优O(1),最差情况下,所有协作站点请求副本率满足条件,且活跃度相同,最后需要比较优先级,则时间复杂度为O(T)+O(T2)=O(T2),即本算法最优状态下时间复杂度

另外,本算法提供undo功能,任意操作在执行后都将被记录在UHB中,即UHB-In操作,假设UHB最大长度为L,存储空间足够情况下追加已执行操作的时间复杂度为O(1),空间达到上限时,将删除头部前移已有操作,时间复杂度为O(L);同样任意操作在Undo后将从UHB中移除,即UHB-Out操作,操作为选择和线性执行,时间复杂度为O(1).

6 实例说明

如图4所示,M1、M2和M3站点执行部分操作后的结构文档存储状态,及各站点在各节点对应的节点与树活跃度情况(如表2).图4中,M1为master,每个协作站点作为TC的节点都被赋予了预设权限,标题节点(TN)、结构节点(SN)与虚拟标题节点(VTN)通过不同的风格显示.

图4 协作站点结构文档存储初始状态

表2 协作站点初始活跃度

在文档初始状态下我们按流程执行图5中的所有操作,操作内容如下:

图5 操作传播流程

O1=UpdateName(n5,newName,oldName,M2)

O2=InsertTile(n8,n10,M3,data,name)

O3=Delete(n1,M3)

O4=Undo(O3,M1)

O5=Delete(n5,M2)

Request(n6):站点M2请求节点n6,图4中所示,n6节点的TC站点为M1且未被赋予权限,默认为Arbitrated,需要经过该节点的CE节点集体仲裁通过后才可获取该节点,仲裁流程参考文献[24].

Request(n4):节点n4的TC站点为M2,权限为locked,编辑上限为2,当M3请求n4时,CE已满,但仍将n4的完整内容返回给M3,但仅具备Readonly权限,一旦任意协作站点推出,释放资源,权限转变为Locked.

Execute(O1,O2,O3):M2执行O1,修改n5标题内容,不改变树结构,执行后广播至其他协作站点;M3执行O2,为n8追加孩子节点n10后广播至其他站点,M2站点接收后由于局部副本中未请求n8,所以操作无需执行.M1执行O3,首先n1的编辑权限可删除,本文算法对删除操作的执行进行了改良,在最近一次合并文档前,所有删除节点只在编辑器中隐藏,如图6所示,O3操作的执行步骤为:①查找n1是否有前一个兄弟节点,结果为不存在;②查找n1是否有后一个兄弟节点,结果为n2;③将n1的孩子节点追加到n2的孩子节点前;④n1节点类型转换为虚拟标题节点,在编辑器中隐藏;⑤操作记录到UHB中,同时将操作O3广播至其他站点.此时各站点的UHB状态如下:

图6 M1删除n1执行流程

M1.UHB=M3.UHB=[O1,O2,O3];M2.UHB=[O1,O3];

Execute(O4):M1撤销上一步操作,即O3,首先判断是否已执行过文档合并操作,没有则判断上一步操作的类型,类型为Delete,将n1的类型由虚拟标题节点转换为标题节点,恢复n1的子孙节点.

Execute(O5):参考O3的执行,n5为叶节点,且即不存在前一个兄弟节点也不存在后一个兄弟节点,可直接转换为虚拟标题节点.

Merge(Str-Doc):M3向master站点(M1)发起合并文档请求,M1接收后同意合并,合并流程详见MCPS2[24]中的merge算法.合并后向其他站点发送最新合并节点内容同时触发UHB-destroy进程:各站点依次清除本地UHB中的操作;若操作为删除操作,则将该节点在后台中彻底删除,不可undo恢复.

如图7所示为3站点执行上述操作后最终结构副本状态,为了简化图像,同时体现局部复制结构不变的特点,我们将3站点的副本合并在一个结构存储图像中,其中虚线部分为M2:Str-Doc.copy=[n1,n2,‘n3’,n4,‘n9’],整体为M3:Str-Doc.copy=[n1,‘n2’,n3,‘n4’,‘n6’,n7,n8,n9,n10],M1(master):Str-Doc=[n1,n2,n3,n4,n6,n7,n8,n9,n10],各站点局部与主副本结构一致.

图7 最终副本状态

master转移:假设M1站点退出协同编辑工作,且没有预设“继承者”,master的选取方式如下:第1步判断各站点的本地副本占比率是否超过设定值P=30%,计算得PM3(68%)>PM2(36%)>P,站点M2和M3均符合筛选条件;第2步对比两站点在结构文档的操作活跃度,在表2初始活跃度的基础上,我们执行前几步操作后更新部分活跃度值,最终M2.DOC.TLV=11,M3.DOC.TLV=17,活跃度值高者继承master,则M1站点退出后由M3作为下一任master,并在第一时刻发起文档合并.若在第2步M2和M3文档操作活跃度相同,则筛选其中最近发起文档合并的站点,即3.

7 总结及展望

移动互联网时代的快速发展,时刻影响着我们的工作和生活,在强调高效、快速理念的今天,移动办公、协同办公或将成为未来社会的主要办公模式.CSCW这一概念的提出,加速了协同领域研究的发展.目前,乐观状态下的协同操作并发控制无论在算法或是应用方面涌现了大量成果,而移动网络与移动终端方面的研究与之相比还远远不够.考虑到移动网络的动态性,移动设备的存储、计算能力等方面的限制,我们将协作文档模型聚焦在结构文档上,通过设计网络连接模式,设置用户权限、节点权限,计算和比对活跃度等降低网络变化对协同工作的影响,并在最大程度上满足多用户操作意愿;另外,为了匹配结构文档的特性,提升算法的实用性,改善删除操作的执行方式,加入支持undo功能的一系列控制算法,最终提升结构文档在移动网络下的协同编辑工作意义.

今后的研究方向主要包括以下几点:

1)将标题粒度的文本结构文档并发控制算法研究扩展至其他粒度,如具备层次结构的表格、图像[4]等;

2)在undo的基础上,支持任意redo[18,19]操作功能;

3)结合MCPS2与本文算法,设计一款支持结构文档协同操作的APP或小程序.

猜你喜欢

副本复杂度文档
全球大地震破裂空间复杂度特征研究
浅谈Matlab与Word文档的应用接口
数字经济对中国出口技术复杂度的影响研究
有人一声不吭向你扔了个文档
轻松编辑PDF文档
Kerr-AdS黑洞的复杂度
非线性电动力学黑洞的复杂度
国家知识产权局公告:专利证书改版
Word文档 高效分合有高招
新副本“战歌之城”怨灵BOSS面面观