2015-11-03 70 views
0

我有一個字節數據流,也稱爲基數256個符號。什麼是最好的算法,在理想情況下將其轉換爲新的符號流,每個符號的基數變化並且只在運行時才知道?輸入字節流和目標基數列表的長度都很長但是有限。所有非負整數,無浮點。此外,目標基數不能保證均勻分配或是256的倍數。從基數256轉換爲多基數並返回的算法

+0

確實輸出流需要具有任何特殊性能(如以某種方式的數字),或者你只需​​要能夠從輸出流和基數得到原來的流背清單? –

+0

@MattTimmermans基本上,分開指定基數的非負整數。是的,原始流必須稍後恢復。 – Reinderien

回答

1

您的問題是算術編碼的一個子集,它被用作許多壓縮算法的最後一個階段。這是最酷的事情在CS學習一種:

http://www.drdobbs.com/cpp/data-compression-with-arithmetic-encodin/240169251 https://en.wikipedia.org/wiki/Arithmetic_coding

如何您的問題具體涉及:

你想要的編碼器是算術解碼器,併爲每個解碼您將使用一個不同大小的字母表(基數),所有符號的概率相同。

編碼器的主循環會做這樣的事情:

int val=0; //information from the stream 
int range=1; //val is in [0,range) 
while(...) 
{ 
    int radix = next_radix(); 
    //ensure adequate efficiency 
    while(range < radix*256) 
    { 
     val = (val<<8)|(next_byte()&255); 
     range<<=8; 
    } 
    int output = (int)(radix*(long)val/range); 
    //find the smallest possible val that produces this output 
    int low = (int)((output*(long)range+radix-1)/radix); 
    //find the smallest possible val that produces the next output 
    int high = (int)(((output+1)*(long)range+radix-1)/radix); 
    val-=low; 
    range = high-low; 
    write(output); 
} 

沒有與處理終止的條件和處理在您的解碼器進行(算術編碼器)的併發症,所以你必須閱讀文學,從我鏈接的東西開始。儘管如此,我希望這能夠讓你瞭解它的工作原理。

好運

+0

是否這樣:'(out * self._range + radix - 1)/ radix'沒有評估這個? '(out * self.range - 1)/ radix + 1'?同樣,'((out + 1)* self._range + radix-1)/ radix' ='((out + 1)* self._range - 1)/ radix + 1' – Reinderien

+0

當out = = 0,因爲整數除法捨去而不是舍入。 (A + B-1)/ B是四捨五入的,(A +(B >> 1))/ B是四捨五入到最近的A/B,並且A/B是A/B向下取整。 –