2017-04-08 42 views
0

我正在編寫一個serialize方法,該方法將Tree轉換爲字符串進行存儲。我正在尋找一個分隔符用於序列化,並不確定要使用什麼。Ruby中的序列化分隔符

我不能使用,,因爲它可能作爲節點中的數據值存在。例如

A 
/\ 
B , 

將序列化到A, B, ,,,打破我的deserialization方法。我可以使用不可打印的ASCII字符嗎?還是我應該猜測哪些字符不可能作爲輸入顯示並用作我的分隔符?

這裏就是我的serialize方法的樣子,如果你很好奇:

def serialize(root) 
    if root.nil? 
    "" 
    else 
    root.val + DELIMITER + 
     serialize(root.left) + DELIMITER + 
     serialize(root.right) 
    end 
end 

回答

2

有我能想到的幾種常用方法:

  • 逃逸:你定義一個逃逸符號,它「逃避「」特殊「解釋。想一想\如何在Ruby字符串文字中充當轉義字符。
  • 固定字段/長度編碼:您事先知道字段開始和結束的位置。 (固定字段是基本上長度編碼的一種特殊情況下,你可以留下出長度,因爲它始終是相同的。)

例轉義:

def serialize(root) 
    if root.nil? 
    "" 
    else 
    "#{escape(root.val)},#{serialize(root.left)},#{serialize(root.right)}" # using , 
    end 
end 

private def escape(str) str.gsub('\', '\\').gsub(',', '\,') end 

實施例爲長度編碼:

def serialize(root) 
    if root.nil? 
    "0," 
    else 
    "#{root.val.size},#{root.val}#{serialize(root.left)}#{serialize(root.right)}" # using length encoding 
    end 
end 

任何,您在size範圍內找到的字符屬於該值。固定字段基本上只是連接這些值,並假定它們都是固定的長度。

你可能想看看現有的序列化格式如何處理它,就像OGDL: Ordered Graph Data LanguageYAML: YAML Ain't Markup LanguageJSONCSV (Character-Separated Values)XML (eXtensible Markup Language)

如果您想查看二進制格式,可以查看Ruby's Marshal formatASN.1

即使你使用轉義,你的想法是尋找一個很少使用的角色是好的,你仍然需要較少使用的角色轉義。想象一下,如果'ee'是eescapee的特徵,它會是什麼樣子。然而,我認爲使用不可打印的字符太過分了:除非你想要設計一個二進制格式(比如Ruby的Marshal,Python的Pickle或Java的序列化),「less可調試性」(即通過簡單地檢查輸出與less)是一個不錯的財產,有一個你不應該放棄。

+0

謝謝!你對使用非printables有什麼想法? – FloatingRock

+1

即使您使用轉義符,您的想法也很好,即使使用較少使用的字符,也仍然需要較少的轉義。想象一下,如果'ee'是eescapee的特徵,它會是什麼樣子。然而,我認爲使用不可打印的字符太過分了:除非你特別想設計一個二進制格式(比如Ruby's Marshal,Python的Pickle或者Java的序列化),否則「可調試性更低」(即更少的可調試性)。通過簡單地用'less'檢查輸出來進行調試)是一個很好的屬性,並且你不應該輕易放棄。 –