2010-04-01 21 views

回答

4

將8個字節視爲一個64位無符號整數,並將其轉換爲十進制,並用零填充到左邊。這應該使盡可能短的字符串,因爲它利用除了開始的所有位置上的所有可用數字。

如果你的數據不是均勻分佈的,還有其他的選擇,考慮霍夫曼編碼,以便最常用的數據模式可以用較短的字符串表示。一種方法是使用第一位數字來編碼字符串的長度。除第一位以外的所有數字都可以視爲長度說明符。這樣,最多20個數字的長度永遠不會超過。 (第20位數字只能是0或1,最高的64位數字是18,446,744,073,709,551,615。)將其他數字精確解釋爲長度的映射應基於您的模式分佈。如果你有10種模式發生,你經常可以例如reserv「0」表示一個數字表示一個完整的序列。

然而,任何這種更復雜的編碼都會引入對更復雜的打包/解包代碼甚至查找表的需求,因此可能不值得付出努力。

+1

... 64位(無符號)整數... – 2010-04-01 07:58:42

+1

但它也將是可變長度,這需要流之間的塊之間的分隔符,這將是....? (因爲所有十位數已被使用。):-) – 2010-04-01 07:59:02

+0

感謝您的評論,我已經更正並延長了我的答案。 – 2010-04-01 08:04:56

1

具有最短長度的結果是將其直接轉換爲小數。這導致最高值爲18446744073709551615,但如果沒有任意長度的整數能力,轉換可能會很困難。

下一個最長的是將它轉換爲八進制爲一個塊。這導致最大長度爲22,值爲1777777777777777777777。這隻需要轉換,並且可以很容易地處理。

下一個最長的是將其轉換爲八進制或十進制的字節。這導致長度爲24,分別有8次重複377255。來回轉換是微不足道的,作爲讀者的練習。

+0

感謝您的回答。對於沒有任意長度的整數能力的第一個選項是困難的,這不是一個真正的問題。您可以將塊分成4個字節的整數,將它們分別轉換爲小數,然後將它們連接起來。由於一個4字節的無符號值最多需要10位數,因此我們仍然有8位字節塊的20位數。你怎麼看? – Hemant 2010-04-01 08:10:56

+0

這當然是一個可行的解決方案,正如將其分解成4個每個5位數字的2個字節塊。 – 2010-04-01 08:22:45

+0

使用2倍4字節解決方案,您需要注意邊界。在高字節中是111 a 1,在低字節中是11,反之亦然?所以你需要使用這個方法總是使用20位數字。 – 2010-04-01 15:29:56

4

效率問題的答案將取決於lot關於8字節塊的典型值範圍。考慮Unicode的UTF-8和UTF-16。 UTF-8編碼主要在西方腳本中編寫的文本非常高效,因爲這些腳本中的大多數字符範圍在0x00到0x7F之間,UTF-8可以存儲在單個字節中。但是,對於主要在東方腳本中編寫的文本進行編碼並不是非常有效; UTF-16或UTF-32是更好的選擇。

如果您有關於the various UTFs的閱讀,他們可能會激發一個解決方案。從根本上來說,他們通過這樣的方式工作,比如允許將很多值直接編碼爲一個字節,但是然後有一個標誌(我認爲這是UTF-8的第一個字節)字節不能說明整個故事,並且需要下一個字節(或兩個,三個或四個)。起點是UTF-8的一個字節,UTF-16是一個字,但概念是相似的。

現在,你正在使用顯着較小範圍的值(0-9而不是0-255),顯然我不建議試圖直接使用UTF,只是概念。例如,說你的大部分價值(直接或按摩)都低於9000,其中不少是低於900萬,只有少數價值超過了這個價值。你可以採用UTF方法,並說塊(你的8字節值)被分成四位數字段,每個編碼塊至少有一個段(四位數)。如果第一個段的值(aaaa)介於0000和8999之間(包括),則它是「終端」段  —這就是實際值。但如果它是9aaa,那意味着有第二個分段,你應該看看aaabbbb(bbbb是下一個分段的值)。如果的值介於0000000和8999999(含)之間,則爲終端;但如果是9aabbbb,則意味着看aabbbbcccc(cccc是下一個段);等我認爲這會給我們這樣的:

00000000000000000000-00000000000000008999 -> 4 digits (xxxx) 
00000000000000009000-00000000000008999999 -> 8 digits (9xxxxxxx) 
00000000000009000000-00000000008999999999 -> 12 digits (99xxxxxxxxxx) 
00000000009000000000-00000008999999999999 -> 16 digits (999xxxxxxxxxxxxx) 
00000009000000000000-00008999999999999999 -> 20 digits (9999xxxxxxxxxxxxxxxx) 
00009000000000000000-08999999999999999999 -> 24 digits (99999xxxxxxxxxxxxxxxxxxx) 
09000000000000000000-18446744073709551615 -> 28 digits (999999xxxxxxxxxxxxxxxxxxxxxx) 
Or special case, just use 26 digits for the last one: (999999xxxxxxxxxxxxxxxxxxxx)

有你最好的情況是四位數字和最差的是28或26,這取決於你是否要特殊情況下,在塊中的最後segement。比每個塊使用20位數字更好(可能)。

現在,這是完全沒有關係,可能不如它的效率,但你明白了。反序列化非常容易,而且序列化可能並不困難。

你可以看到爲什麼我開始評論你的典型值是什麼。如果它們通常高於10,000,000,000,000,000,000,則上述內容不是直接編碼它們的有效方式。但是,如果您的典型值在高端而不是低端,可以使用類似的技術,方法是在編碼之前對該值進行一定程度的按摩。

相關問題