如何对字符串应用一系列插入/删除字符操作?

时间:2010-06-22 10:15:57

标签: java

我有这样的文字:

  

我叫鲍勃,我住在美国。

我对这个字符串的字符有一些参考,例如:

from 3 to 7 chars, deleted
at 3 char, added "surname"
from 20 to 25, deleted
at 25 char ....

但这些陈述没有订购(我无法订购)。

所以,这是一个问题:如何在不丢失字符引用的情况下修改文本? 例如,如果我应用第一句话,我的文字就变成了:

  

我是鲍勃,我住在美国。

我的第三句话不再正常,因为我已经丢失了对原始第20个字符的引用。

请记住,文本很长,所以我不能使用任何索引......

5 个答案:

答案 0 :(得分:7)

首先,如果这个陈述是真的,情况就没那么了:

  

但这些陈述没有订购(我无法订购)。

无序的补丁语句列表可能会导致冲突。无法以自动方式确定正确答案是什么。例如,请考虑以下情况:

         0         1         2
 index:  012345678901234567890
 text:  "apple banana coconuts"
    - delete 5 characters from index 10
    - add "xyz" at index 10
    - delete 10 characters from index 5

根据执行这些陈述的顺序,您将得到不同的结果。

  • 例如,如果您应用(1),然后(2),然后(3),您最终会使用“apple banaconuts” - > “apple banaxyzconuts” - > “apple uts”。

  • 但如果你申请(3),然后(2),那么(1),你结束了“苹果onuts” - > “apple onutsxyz” - > [错误 - 没有足够的字符可供删除!]

您需要对声明进行可重复的,商定的订购,否则您无法继续进行。更糟糕的是,事实证明发现哪些排序是有效的(例如,消除发生不可能语句的所有排序,如“从索引20中删除10个字符”,当没有索引20时)是 {{3 }}


如果事实证明补丁可以按特定顺序应用(或者至少以可重复的,商定的,确定性的顺序),情况会有所改善,但仍然是令人讨厌的。因为任何“补丁”中的索引都可能被前一个索引无效,所以不可能直接应用每个语句。相反,你必须实现一个小的伪diff。我就是这样做的:

  • 浏览补丁语句列表。构建操作列表。操作是具有命令和一些可选参数的对象,以及用于应用该命令的索引。例如,您的操作可能如下所示:
  DeleteOperation(index 3, length 4)
  AddOperation(index 3, text "surname")
  DeleteOperation(index 20, length 5)
  • 执行操作时,请保留对原始字符串的引用并存储“脏指针”。这是字符串中最新的连续索引,它没有对其执行任何操作。必须首先对索引超出脏指针的任何操作进行预处理。

  • 如果您遇到一个干净的操作,其索引小于或等于脏指针,您可以应用它而不需要进一步的工作。脏指针现在移动到该操作的索引。

  • 如果遇到脏操作,索引大于脏指针的操作,则必须先执行一些操作才能应用它。通过查看先前的操作确定应该应用操作的实际索引,然后进行适当的偏移并应用它。

  • 依次执行每个操作,直到不再执行任何操作。

结果是你变换后的字符串。

答案 1 :(得分:0)

您只需要跟踪您对字符串的操作,并在命令列表中添加或减去未来的项目索引。

答案 2 :(得分:0)

每次执行语句时,请遍历整个列表并相应地修改索引。

答案 3 :(得分:0)

听起来像是在进行操作变换

这篇文章在这里讨论它们的理论和实践(并且相当深入)

Understanding and Applying Operational Transformation

如果它们没有任何顺序,你怎么能应用它们?您如何知道在另一次操作之前或之后是否应该应用一个操作?这些操作都不是添加剂吗? (即:所有操作只适用于原始字符串吗?)

答案 4 :(得分:0)

你到底想做什么?

如果您尝试将这些“参考”应用于您的文字,

  

我叫鲍勃,我住在美国。

保持此数据不变。将其复制到另一个字符串,每次需要修改时都应用“引用”。