我有一个特定的数据集,我需要以最紧凑的方式存储为字节数组。它是一个不断增加的整数直播,通常是一个,但不总是一个。每个整数值都有一个字节值的标记。可能存在具有相同值和标记的值,但我只需要存储区别。只有支持的操作是添加新元素,删除并检查元素是否存在 - 我保留此数据集以检查最近是否已“看到”某对。
一些示例数据:
# | value | tag |
1 | 1000 | 0 |
2 | 1000 | 1 |
3 | 1000 | 2 |
4 | 1001 | 0 |
5 | 1002 | 2 |
6 | 1004 | 1 |
7 | 1004 | 2 |
8 | 1005 | 0 |
正如我所说,这是一个直播,但我可以容忍只存储几千个。目标是使其在存储(和RAM)中尽可能保持内存效率,操作可能会花费很多。
如果我没有标签,我可以存储范围或值,(1000-1002),(1002-1005)等,连续通常有大约5-6个值没有间隙。但标签搞砸了这一切。
我目前的方法是在几个字节中对每个值+标记对进行编码 - 标记为一个字节,前一个值为“delta”为1个或多个字节。 这样我需要存储第一个值,1000以上情况,而不是我存储增量 - 0表示#1,#2,1表示#4,1表示#5,2表示#6等。
大多数增量都是小1-10,所以我只能将它存储在一个字节中 - 如果值小到足以容纳7位,则第一位是标志,否则 - 接下来的7位存储一个字节的值三角洲占据。
也许有更好,更紧凑的方法?
答案 0 :(得分:0)
由于您只有127个不同的标记值,因此您可以维护127个不同的表,每个标记对应一个表,这样就不必存储标记。在每个表格中,你仍然可以使用漂亮的技巧和增量。
答案 1 :(得分:0)
将(value, tag)
value
uint32
tag
和uint8
uint32
uint16
对作为存储在数据结构中的典型项目。
使用将std::map<std::uint32_t, std::vector<std::uint16_t>>
映射到D
的数组列表的关联数组数据结构。在C ++术语中,数据结构如下。
(value, tag)
每个数组列表都使用不同的值进行排序,并且永远不会超过2 16 的大小。
让D[value >> 8]
成为此数据结构的实例。我们将(static_cast<std::uint16_t>(value) << 8) + tag
存储在数组列表value
中value
。
这个想法基本上是数据被分页。最重要的3个字节tag
确定页面,然后#include <stdio.h>
#include <stdlib.h>
#define MAXNAMES 10
#define MAXLEN 32
int main(void)
{
char* fileName[MAXNAMES];
int i;
for(i=0; i<MAXNAMES; i++)
if ((fileName[i] = malloc(MAXLEN)) == NULL)
exit(1);
sprintf(fileName[0],"Output.txt"); // your first name is an exception
for(i = 1; i<MAXNAMES; i++) // the rest of the names
sprintf(fileName[i], "Output%d.txt", i+1); // using your offset of 1
for(i = 0; i<MAXNAMES; i++)
printf("%s\n", fileName[i]);
for(i = 0; i<MAXNAMES; i++)
free(fileName[i]);
return 0;
}
的最低有效字节和Output.txt
Output2.txt
Output3.txt
Output4.txt
Output5.txt
Output6.txt
Output7.txt
Output8.txt
Output9.txt
Output10.txt
的单个字节存储在页面中。
这应该非常有效地利用数据结构,因为假设每个页面都包含许多值,那么每个项目使用2个字节。