Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
好主意/坏主意:使用Qt';在非常大的数据集上的QSet?_Qt_Memory Management_Hash_Dataset_Compression - Fatal编程技术网

好主意/坏主意:使用Qt';在非常大的数据集上的QSet?

好主意/坏主意:使用Qt';在非常大的数据集上的QSet?,qt,memory-management,hash,dataset,compression,Qt,Memory Management,Hash,Dataset,Compression,使用QSet跟踪一组非常大的字符串是不是一个坏主意?每个字符串为54个字符(108字节)。这个集合可能包含数千个条目(我还不确定确切的数字)。QSet将仅用于插入和成员资格查询 如果这是个坏主意,我肯定会接受建议。我的54个字符串仅由6个不同的字符组成(例如“aaaaaaaaaaaabbbbbbbbbbb ccccccccc dddddddd eeeeeeeee fffffff”)。这似乎是一个很好的压缩候选,也许?欢迎您提出任何其他建议。我认为您在另一种容器(如std::set、map或vec

使用QSet跟踪一组非常大的字符串是不是一个坏主意?每个字符串为54个字符(108字节)。这个集合可能包含数千个条目(我还不确定确切的数字)。QSet将仅用于插入和成员资格查询


如果这是个坏主意,我肯定会接受建议。我的54个字符串仅由6个不同的字符组成(例如“aaaaaaaaaaaabbbbbbbbbbb ccccccccc dddddddd eeeeeeeee fffffff”)。这似乎是一个很好的压缩候选,也许?欢迎您提出任何其他建议。

我认为您在另一种容器(如std::set、map或vector)上使用QSet不会有任何其他问题。若您想知道是否内存不足,这可能取决于您需要存储多少个字符串,以及是否有更简洁的编码方法。(例如,如果字符总是以相同的顺序出现,但相对长度不同,请存储每个字符的长度,而不是所有字符的长度。)但是,即使50000个字符串也只有5 MB左右,而500000个字符串只有50 MB可存储,不考虑存储开销,在现代机器上,这是一个适度的内存量。

我认为在另一种容器上使用QSet不会有任何额外的问题,例如std::set、map或vector。若您想知道是否内存不足,这可能取决于您需要存储多少个字符串,以及是否有更简洁的编码方法。(例如,如果字符总是以相同的顺序出现,但相对长度不同,请存储每个字符的长度,而不是所有字符的长度。)但是,即使50000个字符串也只有5 MB左右,而500000个字符串只有50 MB可存储,不考虑存储开销,这在现代机器上是一个中等的内存量。

来自您之前的评论:“在我的字符串中,总是有54个字符,每个字符中总是有9个。顺序是唯一会改变的。”


不要存储原始字符串。你可以把它们压缩成实际使用的6个字符,然后把它们组成一个QSet。一个简单的压缩就是{A,b,c,d,e,f},如果字符集是预先知道的(并且只有这6个字符),你甚至可以将它打包成一个16位整数。

来自你之前的评论:“在我的字符串中,总是有54个字符,每个字符中总是有9个。顺序是唯一会改变的。”


不要存储原始字符串。你可以把它们压缩成实际使用的6个字符,然后把它们组成一个QSet。一个简单的压缩就是{A,b,c,d,e,f},如果字符集是预先知道的(并且只有这6个字符),你甚至可以把东西打包成一个16位整数。

意识到,通过使用内置集,你将根据数据的性质进行一些路径级压缩。当然,这取决于容器的实现

查看一些关于基数树、数字搜索树、红黑树等的信息。您将看到不需要存储每个字符串,而是存储模式。例如,让我们简化您的问题:我们只有3个字符,每个字符最多可以出现2次,每个字符串有6个字符长。三个可能的字符串是:

AABBCC、AABCBC和AACBCB

通过这些示例,我们可以使用最多6+3+4=13个节点,而不是全部18个节点。不多,但我也不知道你在做什么。与任何类型的压缩一样,前缀模式被重用越多,压缩就越多

编辑: 数字13和18来自路径级压缩。例如,在straight C(用于参数/讨论)中,如果我将字符串存储类实现为数组的包装器,我可能只会有一个字符指针数组,每个指针引用内存中包含模式的一个点。在我上面给出的示例中,这需要18个字符(6*3=18)。再加上数组的大小(假设sizeof(char*)为4,我们的数组将需要3*4字节的存储空间=12+18或30字节来存储我们的模式

如果我改为将模式存储在一种数字搜索树中,我会做一个小的折衷。我树中的每个节点都将大于1个字节(1个字节用于节点中的字符,4个字节用于每个节点中的“下一个”指针,每个5个字节)。我们存储的第一个模式是AABBCC。这是树中的6个节点。下一个是AABCBC。我们重用第一个树中的路径AAB,CBC只需要额外的3个节点。最后一个模式是AACBCB。我们重用AA,CBCB需要4个新节点。这总共是13个节点*5个字节=65个字节的存储。但是,如果您有很多长的重复路径,请重复在数据的前缀中添加g模式,然后您将看到一些前缀路径级压缩

如果您不是这样,我会研究Huffman或LZW压缩。这将要求您构建一个模式字典,其中包含与之关联的整数。压缩时,您将构建字典,并为文本中的每个模式创建整数id。然后用整数id替换文本中的模式。当我没有时间详细描述这些算法,所以你需要查找它们


这是在简单性/时间上的折衷。如果您的数据允许,请使用较短的方法,只使用内置容器。如果不允许,您将需要更适合您的数据的东西。

请意识到,通过使用内置集,您将根据数据的性质进行一些路径级压缩。当然,这取决于泰纳的实施

看一些关于基数树的信息,数字
  QByteArray ba("112"); // instead of "BBC"
  int num = ba.toInt(0, 6 /*base*/); // num == 44