在C#中对无符号整数值进行可变长度编码的最佳方法是什么?
“实际目的是将可变长度编码的整数(字节)附加到文件头中。”
例如:“内容-长度”- Http报头
能否通过以下逻辑中的一些变化来实现这一点。
我写了一些代码.
发布于 2015-09-11 08:16:46
你应该首先做一个直方图,你的价值。如果分布是随机的(也就是说,直方图计数的每一个都接近另一个),那么您将无法比该数字的二进制表示更有效地编码。
如果您的直方图是不平衡的(也就是说,如果一些值比其他值更多的话),那么选择对这些值使用较少位的编码,而对其他不太可能的值使用更多位的编码可能是有意义的。
例如,如果您需要编码的数字比大的要小2倍,那么您可以使用第16位来告诉您,并且只存储/发送16位(如果是0,那么即将到来的字节将形成一个16位数字,可以容纳32位数)。如果是1,那么接下来的25位将形成32位数。你在这里失去了一点,但因为它不太可能,最后,对很多数字,你赢得更多的比特。
很明显,这是一个很小的例子,扩展到两个以上的例子是Huffman算法,它影响了一个接近最优的“代码词”,这个算法基于数字出现的概率。
还有一种算术编码算法也能做到这一点(可能还有其他算法)。
在所有情况下,没有任何解决方案能够比目前在计算机内存中更有效地存储随机值。
您必须考虑这种解决方案的实现时间和困难程度,而不是最终得到的节省,以知道它是否值得。语言本身在这里是不相关的。
发布于 2010-08-25 06:16:19
如果小值比大值更常见,则可以使用Golomb编码。
发布于 2019-07-20 23:51:30
我知道这个问题是几年前被问到的,但是对于MIDI开发人员来说,我想分享我正在从事的一个midi项目中的一些代码。代码块是基于编写的“最大MIDI”中的一个片段(这个示例是一个经过调整的版本,以满足我自己的需要,但是,这个概念就是……)。
public struct VariableLength
{
// Variable Length byte array to int
public VariableLength(byte[] bytes)
{
int index = 0;
int value = 0;
byte b;
do
{
value = (value << 7) | ((b = bytes[index]) & 0x7F);
index++;
} while ((b & 0x80) != 0);
Length = index;
Value = value;
Bytes = new byte[Length];
Array.Copy(bytes, 0, Bytes, 0, Length);
}
// Variable Length int to byte array
public VariableLength(int value)
{
Value = value;
byte[] bytes = new byte[4];
int index = 0;
int buffer = value & 0x7F;
while ((value >>= 7) > 0)
{
buffer <<= 8;
buffer |= 0x80;
buffer += (value & 0x7F);
}
while (true)
{
bytes[index] = (byte)buffer;
index++;
if ((buffer & 0x80) > 0)
buffer >>= 8;
else
break;
}
Length = index;
Bytes = new byte[index];
Array.Copy(bytes, 0, Bytes, 0, Length);
}
// Number of bytes used to store the variable length value
public int Length { get; private set; }
// Variable Length Value
public int Value { get; private set; }
// Bytes representing the integer value
public byte[] Bytes { get; private set; }
}使用方法:
public void Example()
{
//Convert an integer into a variable length byte
int varLenVal = 480;
VariableLength v = new VariableLength(varLenVal);
byte[] bytes = v.Bytes;
//Convert a variable length byte array into an integer
byte[] varLenByte = new byte[2]{131, 96};
VariableLength v = new VariableLength(varLenByte);
int result = v.Length;
}https://stackoverflow.com/questions/3563271
复制相似问题