news 2026/5/5 4:56:02

GapBuffer高效标记管理算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GapBuffer高效标记管理算法

近笔者正在优化 Android 开源代码编辑器项目 TextWarrior 的一些算法,包括时间、空间两方面。TextWarroir 的文本编辑器算法采用经典的 GapBuffer,其基本思想是利用编辑时的局部性原理,在光标处维护一个缓冲区,实现高效替换。

但是笔者需要对其代码高亮、自动断行等功能用到的标记数组进行优化:

原编辑器的代码高亮标记数组直接采用差分数组存储其文本下标,好处是文章内容频繁更新时差分数组可以只需要改动其中一两个元素的值便能导致后面整体的改动,缺点是查找某个下标时需要从头开始,时间复杂度为

(

)

O(N)。

原编辑器的自动断行标记数组直接存储文本下标,好处是定位时可以采用二分查找,但是当文本改动时需要对整个数组光标处的后半段进行修改,时间复杂度

(

)

O(N)。

不管是差分数组还是直接存下标,貌似都有其缺陷。那有没有一种两全其美的方法呢?答案是有的。这要从 GapBuffer 说起。

GapBuffer 基本思想

GapBuffer 又叫间隙缓冲区,是一种文本编辑器算法,主要对编辑器中频繁的字符串插入、删除操作进行优化。

我们知道,对于中间插入,数组的时间复杂度为

(

)

O(N),而链表的时间复杂度为

(

1

)

O(1)。字符串常常用数组的方式存储,若采用链表,每个字符都会附带一个指针指向下一个字符结点,数据冗余度很高。而 GapBuffer 则实现了对于数组高效的中间插入删除。

GapBuffer 利用编辑时的局部性——编辑操作在一段时间内往往集中在最初光标附近,换位置的情况比较少这一事实——进行优化。GapBuffer 在原字符串数组光标附近维护一个缓冲区(即所谓间隙缓冲区,后文简称间隙),并通过双指针限定该间隙的范围。

由于间隙内的内容实际不可见,当我通过字符串索引获取字符时,需要跳过间隙,此时存在一个下标映射:将获取字符时的逻辑下标映射到所维护字符数组的实际下标。

基本操作

局部性编辑:当光标位于间隙开始位置时,输入时直接将输入内容从间隙开始位置拷贝到间隙,并后移起始指针;删除时,直接前移起始指针。此时时间复杂度为

(

1

)

O(1)。

跨域编辑:若出现跨域编辑,即此时光标位置不在间隙开始处,则需要进行整体复制,以将间隙移动到当前光标处,再进行相关操作。时间复杂度

(

)

O(m),其中

m 表示间隙区移动的距离。

若插入时间隙所剩空间不足,则需要进行扩容,并把间隙后的字符全部向后整体复制。时间复杂度

(

)

O(k),其中

k 为间隙之后的部分数组长度。

插入操作示例:

插入前

|H|e|l|l|o| | | | |W|o|r|l|d|

^ Gap (size=4)

插入后

|H|e|l|l|o|!| | | |W|o|r|l|d|

^ Gap (size=3)

删除操作示例:

删除前

|H|e|l|l|o|!| | | |W|o|r|l|d|

^ Gap (size=3)

插入后

|H|e|l|l|o|!| | | |W|o|r|l|d|

^ Gap (size=4)

基于下标映射的标记记录法

既然 GapBuffer 采用下标映射实现实际下标和逻辑下标的转换,而在编辑的过程中,某个字符的逻辑下标往往是不断变动的,而其实际下标则要稳定得多,因此完全可以记录实际下标实现高效率的标记管理。

记录实际下标,即记录标记在原字符数组中的下标,当间隙发生变动时维护下标的映射关系。可以对比逻辑下标和差分下标,实际下标+映射方式兼具二者有点同时避免了各自的缺陷。

下标映射

在需要访问下标时,会用到 GapBuffer 的下标映射函数将记录的实际下标转为逻辑下标再返回,而增加记录时会把逻辑下标转为实际下标进行记录。

private ArrayList<Integer> records;

private int mapToReal(int i) {

return i < gapStart ? i : i + gapLength();

}

private int mapToLogical(int i) {

return i < gapEnd ? i : i - gapLength();

}

public void getMark(int i) {

return mapToLogical(records.get(i));

}

public void addMark(int i) {

records.add(mapToReal(i));

}

搜索

在需要进行查找时,只需要将逻辑下标转为实际下标并应用二分查找即可,时间复杂度

(

log

)

O(logN),继承了记录逻辑下标的优点,而记录差分下标则必须从头遍历累加。

public int findMark(int i) {

return Collections.binarySearch(records, mapToReal(i));

}

维护

由于记录为实际下标,因此维护需保证与 GapBuffer 的一致性。对于间隙维护的三种情况均需考虑,其时间复杂度也和三种情况基本对等:

局部性编辑:在间隙开头插入时,如果间隙不需要扩容,则记录不变,如果是删除,检查并处理实际下标落入间隙区中的下标,移动或删除,平均时间复杂度

(

1

)

O(1)。由于间隙发生了改变,虽然实际下标没有改变,但映射函数的参数发生变化,因此映射到的逻辑下标会变化。

跨域编辑:在间隙以外的地方插入或删除,此时只需检查移动区间内的下标并加或减去间隙长度,再同上处理插入删除情况,时间复杂度

(

)

O(m),此处

m 为移动区间内标记数量。

间隙扩容:当间隙大小不足插入时需要进行扩容,此时需要将间隙之后的所有标记加上扩容量,时间复杂度

(

)

O(k),此处

k 为间隙之后的标记数量。

实际下标记录的维护在满足局部性的情况下时间复杂度为

(

1

)

O(1),与差分下标记录同级,同时避免了逻辑辑下标记录的不足。当然,实际下标记录的维护难度要比二者大一些。

对比

下标记录方法 逻辑下标 差分下标 实际下标

访问 直接读取O(1) 前缀和O(n) 线性映射O(1)

搜索 二分O(logN) 线性O(n) 二分O(logN)

维护 O(k) O(1) O(1),最坏O(k)

总结

本文讨论文本编辑器经典算法 GapBuffer 的标记记录优化方案,利用算法中的局部性思想提出配套的基于映射的下标记录算法,并对比了 TextWarrior 用到的两种记录方案,表现出该方法在时间复杂度上的优势。另外,局部性原理也是很多算法的依据,在计算机软硬件设计很多地方都有所体现,值得研究。希望本文为读者提供一些参考帮助。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 11:02:08

关闭UAC,关闭cmd终端管理员确认弹窗。

在 Windows 中&#xff0c;普通程序想“无提示直接获得管理员权限”是不可能的。 这是操作系统级别的安全限制。你不能在非管理员上下文中&#xff0c;自动升到管理员&#xff0c;而不经过 UAC 交互&#xff08;就是你说的弹窗确认&#xff09;。不过——如果你坚持要做到“无弹…

作者头像 李华
网站建设 2026/4/30 23:03:00

wl-explorer:重新定义Vue项目中的文件管理开发体验

wl-explorer&#xff1a;重新定义Vue项目中的文件管理开发体验 【免费下载链接】wl-explorer 用于vue框架的文件管理器插件&#xff0c;云盘、网盘。File manager plug-in for vue framework, cloud disk. 项目地址: https://gitcode.com/gh_mirrors/wl/wl-explorer 在…

作者头像 李华
网站建设 2026/5/3 11:14:27

不想让人拷资料,电脑文件和文件夹加密加锁怎么做?小白也能学会

很多人在电脑磁盘中有一些重要的文件需要加密处理,不想让别人随便打开和查看浏览,也不允许别人拷贝出去,如:个人私密保密文件,公司产品研发图档、产品配方、工程项目图纸、客户资料客户图纸、立项文件、财会文件、投资文件、测量报告等,不能让人随便打开和编辑,也不能让…

作者头像 李华
网站建设 2026/4/30 23:58:03

【国产工控系统什么时候才能成为主流?】这是一场“替代”与“跨越”并举的持久战

在制造业数字化转型与供应链安全自主可控的双重浪潮下&#xff0c;国产工控系统何时能成为市场主流&#xff0c;是每一位工业从业者都关心的问题。本文将从技术、生态、市场三个维度展开分析&#xff0c;认为其进程并非简单的时间点&#xff0c;而是一个分行业、分场景的渐进式…

作者头像 李华
网站建设 2026/5/1 0:15:10

GEO 运营商哪家好?2025 年全球 GEO 运营商五强权威榜单

在生成式 AI 全面主导搜索流量分发的 2025 年&#xff0c;GEO&#xff08;生成式引擎优化&#xff09;运营商已成为企业构建 AI 时代品牌流量基建的核心伙伴。从高敏感行业的合规曝光&#xff0c;到跨境品牌的本地化渗透&#xff0c;再到中小商户的低成本获客&#xff0c;不同业…

作者头像 李华
网站建设 2026/5/2 18:13:49

直播抠图技术100谈之15--直播抠图后的画面怎样毫无违和感

在绿幕抠图效果精细&#xff0c; 无色差的情况下&#xff1b; 下面讨论是&#xff1a;在抠图好的前提下&#xff0c; 如何做前景和背景融合的场景。答案是: 调节灯光和相机, 调节设计背景图&#xff0c; 尽量不要调抠图图像&#xff1b; 解释 直播不同于影视后期, 可以通过dav…

作者头像 李华