我有一串类似a:b
,d:a
,t:w
,i:r
等格式的字符串。由于我不断添加这些字符串,因此结束,它变成一个很大的字符串。
例如,我正在尝试编码:
a:b -> 1
d:a -> 2
etc.
我的目的是使最后的字符串尽可能小以节省内存。因此,我需要给出现最大次数的字符串赋予一个数字值。
我想到的是以下方法:
创建:map<string, int>
-这将保留字符串及其计数。最后,我将最大计数值的字符串替换为1,然后将其替换为2,依此类推,直到map的最后一个元素。
当前最终字符串的大小约为100,000个字符。
我不能在速度上妥协,请建议是否有人有更好的技术来实现这一目标。
答案 0 :(得分:0)
如果我正确理解您的输入字符串的范围是“ a:a” ...“ z:z”,则您只需要计算流中每个字符串的出现,而不管顺序如何。如果您的分布足够,则可以使用uint16_t将它们算在内。 映射是使用树来实现的,因此数组在内存和时间上都比映射高效。 所以你可以定义一个数组
array<array<uint16_t, 26>, 26> counters = {{}};
并假设您输入的是例如input = "c:d"
,则可以按如下所示填充数组
counters[input[0]-'a'][input[2]-'a']++;
最后,您可以像这样打印出输入的频率
for (auto i=0; i < counters.size() ; ++i) {
for (auto j=0; j < counters[i].size(); ++j) {
cout<<char(i+'a')<<":"<<char(j+'a')<<" "<<counters[i][j]<<endl;
}
}