我有两个以下形式的排序列表:
A: 30,31,32,35,39,41,59,71,75,79,81,82,85,...
B: 28,29,33,39,40,41,71,75,79,81,82,83,84,85,86,..
即:列表B包含列表A的大部分元素(但不是全部),并添加了一些内容。有没有一种有效的方法可以用压缩形式存储这两个列表。我打算完全存储A.并且打算只在B中存储更改。是否有一些有效的算法可以利用它?
答案 0 :(得分:3)
最简单的方法是存储合并的列表,并让每个元素标识它所属的列表:
[A]1, [B]5, [A, B]16, [A]17, [A, B] 18, ...
这可以作为结构数组实现:
struct sorted_list_with_flag_s {
char membership;
int value;
}
struct sorted_list_with_flag_s * joined_list;
for (i = 0; i < list_length; i++)
if (joined_list[i].membership & 0x1) { /* joined_list[i].value is in A */}
if (joined_list[i].membership & 0x2) { /* joined_list[i].value is in B */}
或者为了节省更多空间,请分别使用会员矢量:
char * membership_vector;
int members = 2; // first bit for even bits for A, odd for B
int * joined_list;
for (i = 0; i < list_length; i++)
if (membership_vector[i * members / 8] & (1 << ((i * members) % 8)))
{ /* joined_list[i] is in A */}
if (membership_vector[(i * members + 1) / 8] & (1 << ((i * members + 1) % 8)))
{ /* joined_list[i] is in B */}
答案 1 :(得分:0)
对于列表A,由于您完全存储它并且不希望更改它,我会使用像其他人建议的算法,存储基数和差异列表。另外,我会扫描A列表以确定增量及其频率,然后我将使用霍夫曼码编码增量,其中最短的H代码用于最频繁的增量。我会存储一个映射表来将delta映射到H代码。这假设列表的大小非常大(合理的假设,因为你想压缩它)。也就是说,在列表中查找特定数字的效率将低于其他存储方法。
对于B来说,与A的关系似乎无关紧要。相反,您只需要另一个排序的整数列表,您希望这些整数随时间变化。如果存储效率是您最重要的考虑因素,请对列表A使用相同的方法,并在每次插入和删除时支付性能价格。
答案 2 :(得分:0)
您可能有3个列表:common
(可以使用std::set_union
计算)
以及UniqueA
和UniqueB
,其中包含A
和B
的唯一元素。
答案 3 :(得分:-1)
28,29,33,39,40,41,59,71,75,79,81,82,83,84,85,85,..
等于
base=28
+0, +1, +4, +6, +1, +1, +18, +12, +4, +4, +2, ..
then each number is described by a few bits. Also they are repeated
so you can store number of repeatitions at the unused bits if there is any.
if Maximum increment is 15, then any element can be stored as 4 bits.
If they are repeated, you can use an extra nibble or byte for number of repeats.
You can even use the increment of increment where necessary such as:
+0, +1, +3, +2, -5, -5, +17, -6, -8 ,... so even lesser bits may prove useful.
and remaining bits can be used for more number of repeats or formatting hints.