[英]How can I compress a sequence of integers?
我有一個數組,其中包含-255到+ 255.eg范圍內的數據。數組可以是這樣的:
int data[]={234,56,-4,24,56,78,23,89,234,68,-12,-253,45,128};
這里,必須在解壓縮時保留順序,例如在第一個術語234之后,必須來56。
那么,有什么方法可以壓縮任何無法觀察到任何重復模式的任意數字序列?
范圍-255到255表示511個值 - > 9位。 如果單獨使用符號,則1位用於符號,1位用於值。
您可以將數組編寫為字節數組,每個字節值將是相關int的絕對值。
在單獨的區域(長或可能是字節數組)中,存儲符號位。
如果數據中確實沒有模式,則無法使用有用的壓縮算法。 甚至不打擾嘗試!
當然,在這種情況下,因為所有數字都在一個受限制的范圍內,所以你的位數確實有一個模式 - 即你的高位全部為0(正)或全1(負)。
因此,如果您想要合理有效地壓縮(假設您擁有足夠長的數字陣列以使其值得),則像zip這樣的標准壓縮算法將起作用。
或者,您可以利用有效使用9位數的事實。 因此,您可以通過將數字布置為9位塊的長流並將其放入字節數組來推廣自己的壓縮算法。
在您的情況下(當無法觀察到重復模式時), 可變長度編碼可能對您有所幫助。
例如, Elias gamma編碼和Exponential-Golomb編碼 。 一般的想法 - 小數字只需要很少的位來編碼。 Exp-Golomb編碼用於H.264 / MPEG-4 AVC視頻壓縮標准。 使用它對序列進行編碼和解碼非常容易,實現這種編碼也不是很難。
編碼所有整數的方法是設置一個雙射,將整數(0,1,-1,2,-2,3,-3,...)映射到(1,2,3,4,5,6) ,7,...)編碼之前。
例如:
序列(雙射后) [ 0, 2, 5, 8, 5, 2 ]
101100110000100100110011
[ 0, 2, 5, 8, 5, 2 ]
將被編碼為101100110000100100110011
- 正如您所看到的 - 此序列中沒有重復模式,但它僅以24位編碼。
解碼過程的簡短描述:
從輸入流讀取並計數前導零位(直到找到非零位) - > zero_bits_count
從輸入流讀取下一個(zero_bits_count + 1)位 - > 二進制
將二進制轉換為十進制
返回(小數 - 1)
1... -> no leading zeros, zero_bits_count = 0 -> read next 1 bit -> [1]... -> [1] is 1 -> 1 - 1 = 0
011... -> [0] - one leading zero, zero_bits_count = 1 -> read next 2 bits -> [11]... -> [11] is 3 -> 3 - 1 = 2
00110... -> [00] - two leading zeros, zero_bits_count = 2 -> read next 3 bits -> [110]... -> [110] is 6 -> 6 - 1 = 5
等等
如果數字基本上是隨機且均勻分布的,並且要保留順序,那么您可以做的最好的是每個符號大約9位。 在9位時,將使用單個9位值,即2的補碼表示中的-256。 這很方便,因為您可以將其用作結束符號來標記列表的結尾。 然后你還編寫了列表的長度,無論如何都需要以某種方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.