【发布时间】:2021-08-24 02:05:52
【问题描述】:
我有一个相当简单的问题:我有一个std::map<int,T> 和另一个std::set<int>(也可以是std::vector 或类似的)。
在地图中我存储项目,在另一个容器中我存储(地图的)收藏夹。
在某些时候,我需要从地图中检索(所有)项目,但从另一个容器定义的收藏夹开始。
这是我的最小复制,我解决它非常丑陋,而且无效:
#include <iostream>
#include <string>
#include <set>
#include <map>
using namespace std;
map<int, string> myMap;
set<int> myFavorites;
int main()
{
myMap.emplace(1, "but I don't like this");
myMap.emplace(12, "So it will go below");
myMap.emplace(31, "This one will come first, and");
myMap.emplace(44, "under my favorites");
myMap.emplace(52, "then this will follow");
myFavorites.insert(52);
myFavorites.insert(31);
cout << "My map:" << endl;
for(auto p : myMap) {
cout << "#" << p.first << "=" << p.second << endl;
}
cout << endl << "My favorites:" << endl;
for(auto p : myFavorites) {
cout << "#" << p << endl;
}
cout << endl << "All items starting with my favorites:" << endl;
for(auto p : myFavorites) {
auto item = myMap.find(p);
if (item != myMap.end()) cout << "#" << item->first << "=" << item->second << endl;
}
for(auto p : myMap) {
if (myFavorites.find(p.first) != myFavorites.end()) continue;
cout << "#" << p.first << "=" << p.second << endl;
}
}
真正困扰我的是最后一个循环,每次迭代都会在set 上调用find。
需要的输出是:
All items starting with my favorites:
#31=This one will come first, and
#52=then this will follow
#1=but I don't like this
#12=So it will go below
#44=under my favorites
这里是 Coliru 中的上述源代码,以使其更容易:https://coliru.stacked-crooked.com/a/731fa76d90bfab00
map 和 set 都可以更改,但替换需要实现与原始接口相同的接口。
我正在寻找一种比我原来的“蛮力”解决方案更有效的方法。
请注意:地图不得“重新排序”!我只需要使用自定义排序查询(检索)它的项目!
注2:我知道地图可以有一个比较运算符。但我通常需要原始顺序,有时我需要自定义排序!
注意 3:Boost 不可用,编译器支持 C++14。
【问题讨论】:
-
也许您可以考虑使用额外的存储空间,特别是一个名为“favorite”的
vector <pair<int, T>>和一个名为“other”的。然后,您可以通过简单地遍历所有地图元素来实现这种输出 - 对于每个元素,检查它是否在“收藏夹”集中。如果是,则将其添加到“收藏夹”,否则将其添加到“其他”。最后,要获得输出,只需先在“收藏夹”中打印所有内容,然后在“其他”中打印所有内容。这样做的问题是存储需求可能等于地图的大小,如果地图很大,这可能会很糟糕。
标签: c++ sorting dictionary