我必须处理大量小数的序列,大约一百万,我必须在4KB中尽可能多地(更多更好)。显然,放置所有这些空间的空间太小了。此外,虽然这是一个特定的场景,但我会尽可能地回答一般问题。
这些数字不遵循任何模式,但这是一个小脚本对其分布的说法:
407037 times 1
165000 times 2
85389 times 3
52257 times 4
34749 times 5
23567 times 6
15892 times 7
11183 times 8
7636 times 9
5402 times 10
3851 times 11
2664 times 12
2023 times 13
1547 times 14
1113 times 15
... many more lines ...
1 times 62
62是我拥有的最大数字,所以让我们设置我们关心的最大数量为64.如果方法很容易适应更大的最大数量,那就更好了。
以下是数字的示例:
20
1
1
1
13
1
5
1
15
1
3
4
3
2
2
一种天真的方法就是每个数字使用6位,但我认为我们可以做得更好。
编辑:在评论中讨论后添加一些信息。
我还在微处理器上有2KB的ram和十几个周期来解码每个数字。我需要按顺序从第一个数字中存储尽可能多的数字。
编辑:看看graybeard的评论和我的后续行动。
答案 0 :(得分:3)
执行此操作的正确方法是Rangecoding
,Huffman
或Shannon-Fano
,您可以通过网络在任何数字通信博客中看到,所以我是不完全解释你这些。
我可以建议你一个自定义方法,这非常简单,你可以将它与其他方法进行比较,如果你可以使用它来存储更多的数字。
我发现您的脚本中没有0's
。因此,只需将每个数字减1(解码时,将1加到解码结果中)。使用4或7位编码数字。所有高达8
的数字都可以用3位表示。如果数字为n <= 8
,则将第1位设置为0
,接下来的3位可以表示该数字。否则,如果数字为n > 8
,则将第1位设置为1,并将数字表示为6位。
虽然在Huffman
或Shannon-Fano
,但很少有表示可以超过20 bits
。
答案 1 :(得分:1)
为了提供正确答案,需要知道 - 解码器大小是否也有限,或者解码大小没有限制? 如果解码器没有限制(仅限数据),建议您使用rangecoder或Huffman coding。 Rangecoder具有更好的压缩性,但具有广泛的算术运算用途。
但是,两个解码器都使用内存来代码和统计表。所以,或许,更好的答案可以创建更简单的东西(自定义压缩器),但代码简单紧凑,没有任何表格。因为简单,代码紧凑,我可以提出run-1算法。这个算法对你的数据(范围编码器或霍夫曼更好)效率不高,但是没有任何表格的平凡紧凑型解码器。
Idea - 序列可以包含零个或多个bit_1,并使用bit_0作为符号分隔符。例如,如果我们想用run-1编码序列:
1, 1, 2, 1, 5
会有位序列:
0-0-10-0-11110
在那里,你只需要计算顺序bit_1的数量,加1,并将返回值作为解码数。
答案 2 :(得分:1)
可能通过结合游程编码尝试稍微好于直接的Huffman。
如果计算连续相同的元素,则可以将序列重写为(值,计数)对。每个这样的对都有一定的概率,你可以在这些上使用霍夫曼编码。 (我不是要分别编码值和计数,而是将对作为一个整体)。
您的样本产量
let numbersTest = resultTitles[indexPath.row]
if let number = Int(numbersTest){
print(number)//contains onlyy number
}else{
print("notnumber")//Not number
}
单身人士(实际上)将像以前一样进行编码,并且有更多机会压缩更长的跑步。
您可以限制支持的最大数量;如果实际计数超过限制,插入几对没什么大不了的。
第一步是计算计数值的直方图,以查看是否有足够的重复值来进行此方法。
或者,您可以尝试对增量进行霍夫曼编码(连续值之间的符号差异)。如果有很多重复,则频率为0将更高,增加熵。显然,增量的运行长度编码也是可能的。
答案 3 :(得分:1)