我们知道大多数代码编辑器都使用Boyer-Moore算法实现字符串搜索。它是如何实现字符串替换算法的呢?
答案 0 :(得分:1)
我猜测,现在大多数文本编辑器使用单个内存块来保存整个文件,或者使用更大尺寸的行或块数组,每个行指向其自己的内存块。 (过去采用了更多有趣的技术。一种方法是将所有文本放在光标位置左侧或上方“按下”固定大小缓冲区的左端,并将所有文本放在右侧或下方“按下“右端,中间有自由空间的间隙。然后插入或删除字符的常见操作可以在恒定时间内进行!将光标k位置向右移动需要从左端滑动k个字节。右段到左段的右端,即移动光标现在是线性时间操作!)
假设文本以“普通”方式存储(即不是上面描述的左右光标相关缓冲区对),优化替换操作的方法并不多,特别是如果替换文本更长比搜索文本 - 在这种情况下,没有逃避这样的事实,即每次替换时必须在内存中向前分流行/块/文件的其余部分。你可以做的最好的事情就是避免多次O(n)复制操作 - 即不删除搜索字符串,然后一次插入替换字符串一个字符,分流行/块/文档的其余部分一次转发一个字符,因为后一步将花费O(n ^ 2)时间。相反,将文档文本的其余部分分开足够远,以便在一个O(n)步骤中为替换字符串腾出空间。
如果替换字符串比搜索文本短,则可以使用两个指针from
和to
向前扫描,始终从一个指针复制到另一个指针。在进行替换后,to
将开始落后于from
。这是安全的,因为to <= from
总是成立,所以你永远不会写下你以后要读的东西。
实际上,如果替换字符串比搜索字符串长,并且搜索字符串的后缀也不是搜索字符串的前缀,那么您可以安全地从一端搜索向后 O(n)通过。后缀/前缀要求是必要的,以避免以下情况,根据扫描方向会产生不同的行为:
Search and replace "abcabc" with "xyz" in document text "abcabcabc":
S&R using forward algo gives: xyzabc
S&R using backward algo gives: abcxyz