我正在编写一个C++程序,用于处理长流的符号,并需要存储信息以供进一步分析,在流中出现某个长度的符号序列的位置。例如,在二进制流中:
100110010101
我有一个长度为6的序列如下:
- 从0开始的100110
- 从1开始的001100
- 从2开始的011001
- 等等。
我需要存储的是所有位置的向量,我可以在其中找到一个确定的序列。因此结果应该是类似哈希表的表格,看起来像这样:
序列/ 位置
10010101 | 1 13 147 515
01011011 | 67 212 314 571
00101010 | 2 32 148 322 384 419 455
等等。
现在,我发现将字符串映射到整数很慢,因此由于我提前知道流中的符号情况,我可以利用它将这些固定长度的序列映射到整数。
下一步是创建一个映射,将这些“表示整数”映射到表中相应的索引,我会在其中添加这个序列的下一个出现位置。然而,这很慢,比我能承受的要慢得多。我尝试了std和boost库的有序和无序映射,都没有足够的效率。我测试了一下,这个映射是真正的瓶颈。
这里是伪代码循环:
for (int i=seqleng-1;i<stream.size();i++) {
//compute characteristic value for the sequence by adding one symbol
charval*=symb_count;
charval+=sdata[j][i]-'0';
//sampspacesize is number off all possible sequence with this symbol count and this length
charval%=sampspacesize;
map<uint64,uint64>::iterator &it=map.find(charval);
//if index exists, add starting position of the sequence to the table
if (it!=map.end()) {
(table[it->second].add(i-seqleng+1);
}
//if current sequence is found for the first time, extend the table and add the index
else {
table.add_row();
map[charval]=table.last_index;
table[table.last_index].add(i-seqleng+1)
}
}
所以问题是,我能否使用比地图更好的东西来记录表中对应索引的记录,或者这是最好的方法了吗?
注意:我知道这里有一个快速的方法,那就是创建足够大的存储空间以容纳每个可能的符号序列(意味着如果我有长度为10且有4个符号的序列,则我保留4 ^ 10个插槽并可以省略映射),但我将需要使用长度和符号数量,这将导致保留远超计算机容量的内存量。但实际使用的插槽数不会超过1亿(这由最大流长度保证),这可以很好地存储在计算机中。
如有不清楚的地方,请随时提问,这是我在这里的第一个大问题,所以我缺乏表达自己的经验,以便让其他人理解。
std::map<sequence, tableIndex> map
和MyVector<MyVector<Position>>
。为什么不直接使用std::map<sequence, std::vector<Position>> map
? - Jarod421
和0
,那么为什么不将其存储为unordered_map
在例如uint_8t
上,其中您的键是对应于二进制展开式的数字?在读取源字符串时,您只需要逐个字符地读取,并随着读取而进行左移。 - donkopotamusmap::insert
的返回值。 - Jarod42