如何解决c ++用于制作计数器的更有效的数据结构和算法我用查表
我的问题是:我给出了一系列查询和一系列引用,并且我想计算它们之间所述键的出现次数,但前提是它们具有匹配的键。我选择使用LUT是因为我认为它会有效地帮助我,但是我不确定是否有更好的方法,或者使用LUT的方法效率不高。
我具有以下数据结构。
unordered_map <int,set<int>> Reference_map1,Reference_map2,...,Reference_mapM;
// to story all the reference maps by their neightas
unordered_map <string,unordered_map <int,set<int>>> ReferenceMaps;
unordered_map <int,set<string>> LUT // look up table
// N is significantly greater than M
unordered_map <int,set<int>> query_map1,query_map2,query_mapN;
Reference_mapi
和query_mapj
Reference_map1[111] = {0,1,2};
Reference_map1[333] = {1,2,3};
Reference_map1[888] = {2,8,0};
Reference_map2[111] = {1,5,9};
Reference_map2[999] = {0,7,4};
ReferenceMaps['Reference_map1']=Reference_map1;
ReferenceMaps['Reference_map2']=Reference_map2;
query_map1[111] = {8,6};
query_map1[333] = {4,3};
query_map2[222] = {3,6,8};
query_map2[999] = {2,3,5};
我如何存储查询表LUT
这样一来,无论我从“ query_mapj”获得什么键,我都只会得到必要的Reference_mapi
s
LUT[111] = {'Reference_map1','Reference_map2'}
LUT[333] = {'Reference_map1'}
LUT[888] = {'Reference_map1'}
LUT[999] = {'Reference_map2'}
例如111
中的query_map1
会同时给出'Reference_map1'和'Reference_map2',因为它们都具有键111
。
另一方面,999
中的query_map2
仅给出'Reference_map2',因为它只有键999
。
所以它会像这样:
unordered_map<string,int> MakeCounter(
unordered_map <int,set<int>> &query_map,unordered_map <string,set<int>>> &ReferenceMaps
){
unordered_map<string,int> RefName_Counter;
set<string> ReferenceNameSet;
// Update the RefName_Counter
for (const auto &key2nameset:query_map) {
// Check if this hash is in the LUT
if (LUT.count(key2nameset.first) <= 0){ continue; }
// Update Counter
ReferenceNameSet = LUT[key2nameset.first];
for (const auto &it : ReferenceNameSet){
if (RefName_Counter.count(it) > 0)
RefName_Counter[it]++;
else
RefName_Counter[it] = 1;
}
}
return RefName_Counter;
}
// The results should be like this
Counter1 = MakeCounter(query_map1,ReferenceMaps);
/*
Counter1['Reference_map1'] = 2; // because they share keys : 111 and 333
Counter1['Reference_map2'] = 1; // because they share keys : 111
*/
Counter2 = MakeCounter(query_map2,ReferenceMaps);
/*
Counter1['Reference_map2'] = 1; // because they share keys : 999
*/
是否有更好的方法来为每个Counteri
获得query_mapi
?
解决方法
考虑到我上面的评论,这就是我得到的。
已调整为保留原始数据,但这似乎是额外的功劳:)
unordered_map<int,int> MakeCounter(const unordered_map <int,set<int>>& qs,const vector<unordered_map <int,set<int>>>& refs)
{
unordered_map<int,int> counters;
for (size_t i = 0; i < refs.size(); ++i)
{
for (auto q : qs)
{
if (refs[i].find(q.first) != refs[i].end())
counters[i]++;
}
}
return counters;
}
int main()
{
vector<unordered_map <int,set<int>>> References = {
{ {111,{ 0,1,2 } },{333,{ 1,2,3 } },{888,{ 2,8,0 } },},{ {111,5,9 } },{999,7,4 } },}
};
vector<unordered_map <int,set<int>>> Queries = {
{ {111,{ 8,6 } },{ 4,{ {222,{ 3,6,8 } },3,5 } },}
};
unordered_map<int,int> m0 = MakeCounter(Queries[0],References);
unordered_map<int,int> m1 = MakeCounter(Queries[1],References);
}
,
这是一个评论;我正在使用“答案”来正确设置代码片段的格式。
这会两次搜索您的LUT
:
// Check if this hash is in the LUT
if (LUT.count(key2nameset.first) <= 0){ continue; }
// Update Counter
ReferenceNameSet = LUT[key2nameset.first];
它也无缘无故地制作了一个副本。
我相信,在地图中索引不存在的元素会插入该元素,所以
if (RefName_Counter.count(it) > 0)
RefName_Counter[it]++;
else
RefName_Counter[it] = 1;
有效:
RefName_Counter[it]++;
因此,外部for
循环变为:
for (const auto &key2nameset:query_map) {
// Check if this hash is in the LUT
auto iter = LUT.find(key2nameset.first);
if(iter == LUT.end()) { continue; }
// Update Counter
for (const auto &it : *iter){
RefName_Counter[it]++;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。