編輯器的資料結構

2021-08-30 08:16:19 字數 1994 閱讀 2129

我從來沒有實現過任何乙個編輯器。但對於這麼乙個我們每天都使用的工具,如何高效的實現其內部結構是乙個有趣的話題。首先, 乙個高效的演算法,以下幾點是值得考慮的重點:

1. 所佔的空間大小

2. 插入,刪除的效率。

最直接的方法是使用乙個陣列, 陣列的每乙個成員對應乙個相應的字元。這樣不需要任何冗餘空間,但是缺點也是顯而易見的: 每次插入和刪除都要進行陣列拷貝的動作。

乙個初步的提高, 我們是否能夠在刪除的時候不做這個拷貝動作, 而使用乙個特殊的字元來取代。但是我們如何避免在插入時進行陣列拷貝的動作呢。這個問題將直接導致兩個常用的編輯器資料結構: gap buffer 和 piece table.

gap buffer:

就是在插入和刪除的地方使用乙個buffer,這個buffer可以看成在陣列中的乙個空白區域。這個區域隨著編輯器游標的移動而移動。 例項如下:

陣列:我們使用  【                          】編輯器

^ 插入 「文字」 

我們使用文字【                         】編輯器 

^

移動游標至文字之前:

我們使用【                       】文字編輯器      

刪除 「文字」:

我們使用【                           】編輯器

gap buffer 相應的資料結構也很簡單:

public class 

gapbuffer

gapbuffer 在游標移動的時候要進行陣列拷貝。所以在檔案比較大的時候,通常我們要使用乙個鍊錶的gapbuffer來儲存文字。在上述的結構中,使用檔案系統的page size 來構建buffer。當然我們還需要考慮,合併和擴充套件buffer的操作。

gapbuffer 的使用者包括emacs.

piece table:

相比較gap buffer, piece table稍顯複雜一些。piece table的實現由兩個buffer組成,乙個buffer是唯讀的,另乙個buffer是可寫的 (只能新增)。每乙個piece 代表了這兩個buffer中的一塊記憶體。每乙個piece可以表示如下:

public class 

piece

最終的檔案可以看成所有piece的合在一起。示例如下:

buffer 0:【我們使用編輯器  】                 

buffer 1:【                                 】

buffer index

offset

length00

7 插入 「文字」

buffer 0:【我們使用編輯器  】                 

buffer 1:【文字                                 】

buffer index

offset

length0

0 4

1 0

2043

刪除 「我們」:

buffer 0:【我們使用編輯器  】                 

buffer 1:【文字                                 】

buffer index

offset

length 0

0 41 0

2 04 3

在 piece table 的實現中,兩個buffer的內容都不會被刪除。每次新增則是在buffer 1中增加乙個piece.而每次刪除僅僅是改變table的內容。這樣的乙個好處是我們只需要記住table的變化就可以實現undo和redo了。在每乙個piece中加入一些其它的描述符,我們可以記錄諸如字型等資訊 。 很多文字編輯器都使用這種方法。

編輯器資料結構

data structures for text sequences 這篇文章給出了實現乙個文字編輯器所需要的的資料結構和不同結構的效率。文章指出有六種資料結構可以實現編輯器,分別是linked list,array,gap,line spans,piece tables和fixed size bu...

資料結構棧之行編輯器

time limit 1000ms memory limit 65536k 有疑問?點這裡 由於使用者在終端上進行輸入時,不能保證不出差錯,因此,若在編輯程式中,每接受乙個字元即存入使用者資料區 的做法顯然不是最恰當的。較好的做法是,設立乙個輸入緩衝區,用以接受使用者輸入的一行字元,然後逐行存入使用...

資料結構實驗之棧 行編輯器

time limit 1000ms memory limit 65536k 有疑問?點這裡 乙個簡單的行編輯程式的功能是 接受使用者從終端輸入的程式或資料,並存入使用者的資料區。由於使用者在終端上進行輸入時,不能保證不出差錯,因此,若在編輯程式中,每接受乙個字元即存入使用者資料區 的做法顯然不是最恰...