我正在寻找最佳的数据结构来为文本添加样式(比如在文本编辑器中)。该结构应允许以下操作:
- 快速查找绝对位置X处的所有样式
- 在任意位置快速插入文本(该位置之后的样式必须移动)
- 文本的每个位置必须支持任意数量的重叠样式
我已经考虑过包含文本范围的列表/数组,但它们不允许在不重新计算插入点之后所有样式的位置的情况下快速插入。
使用相对偏移量的树结构支持第二个要求,但是当我向文本添加大量样式时,树将快速退化。
还有其他选项吗?
我正在寻找最佳的数据结构来为文本添加样式(比如在文本编辑器中)。该结构应允许以下操作:
我已经考虑过包含文本范围的列表/数组,但它们不允许在不重新计算插入点之后所有样式的位置的情况下快速插入。
使用相对偏移量的树结构支持第二个要求,但是当我向文本添加大量样式时,树将快速退化。
还有其他选项吗?
我从未开发过编辑器,不过这个想法怎么样:
我认为可以扩展用于存储文本字符本身的方案,当然具体取决于您的实现细节(语言、工具包等)和性能及资源使用要求。
与其使用单独的数据结构来存储样式,我更喜欢使用带有引用的字符,指向适用字符的数组或列表。具有相同样式集的字符可指向相同的数组或列表,因此一个可被共享。
插入和删除字符并不会影响样式本身,除了改变对它们的引用数量,这可以通过一些引用计数来处理。
根据您的编程语言,您甚至可以通过指向列表的一半来压缩一些内容,尽管此操作所需的额外管理可能使其更加低效。
这个建议的主要问题在于内存使用。在C语言中编写的ASCII编辑器中,每个字符与指针捆绑将使其有效内存使用量从1字节增加到12字节,因为结构对齐填充。
我的建议是将文本分成小的可变大小块,以便您可以高效地压缩指针。例如,在C语言中,32个字符的块可能如下所示:
struct _BLK_ {
unsigned char size;
unsigned int styles;
char content[];
}
至于文本存储本身,树听起来是个好主意。也许是一个二叉树,每个节点值将是子节点值的总和,最终叶节点将指向其节点值作为其块大小的文本块?根节点值将是文本的总大小,每个子树理想地持有您文本的一半。不过,您仍然需要自动平衡它,有时必须合并半空的文本块。
如果您错过了,我不是树的专家:-)
编辑:
显然,我建议的是这种数据结构的修改版本:
http://en.wikipedia.org/wiki/Rope_%28computer_science%29
正如这篇文章所提到的:
编辑2:
在所提出的数据结构中,删除应该相对较快,因为它将归结为在数组中进行字节移位和样式掩码上进行一些位运算。插入基本上是相同的,除非块填满。可能有意义在每个块内保留一些空间(即样式掩码中的一些位),以允许未来直接在块中插入少量新文本而无需更改树本身。
像这样将字符和样式捆绑在块中的另一个优点是,其固有的数据局部性应该比其他替代方案更有效地利用CPU缓存,从而在某种程度上提高处理速度。
与任何复杂的数据结构一样,您可能需要使用代表性测试用例进行分析或自适应算法来确定其操作的最佳参数(块大小,任何保留空间等)。