C++ 对无序映射STL搜索
我想创建一个hashmap,我可以以某种方式搜索键的两个部分。假设我有一双鞋,我想把它作为钥匙。我不想搜索精确的{string,id},但有时搜索int,有时搜索字符串,这可能吗?是的,可能!然而,它不是很有用,而且设计很糟糕 解决方案是使用自定义比较类型,该类型将自定义比较操作。如果您想要比较器中的一个行为,那么您只需要一个自由上下文比较类型,它可以执行您想要的任何操作 但是,如果您想根据需要从映射外部更改行为,您将使用一个比较器,该比较器具有超出映射的上下文C++ 对无序映射STL搜索,c++,dictionary,hashmap,C++,Dictionary,Hashmap,我想创建一个hashmap,我可以以某种方式搜索键的两个部分。假设我有一双鞋,我想把它作为钥匙。我不想搜索精确的{string,id},但有时搜索int,有时搜索字符串,这可能吗?是的,可能!然而,它不是很有用,而且设计很糟糕 解决方案是使用自定义比较类型,该类型将自定义比较操作。如果您想要比较器中的一个行为,那么您只需要一个自由上下文比较类型,它可以执行您想要的任何操作 但是,如果您想根据需要从映射外部更改行为,您将使用一个比较器,该比较器具有超出映射的上下文 struct CompareCo
struct CompareContext
{
bool id = false;
};
struct Comparer
{
const CompareContext& ctx;
using arg_t = std::pair<std::string, int>;
Comparer(const CompareContext& ctx) : ctx{ ctx } {}
bool operator()(const arg_t& first, const arg_t& second) const
{
if (ctx.id)
{
std::less<int> l;
return l(first.second, second.second);
}
else
{
std::less<std::string> l;
return l(first.first, second.first);
}
}
};
int main()
{
CompareContext ctx;
Comparer comp{ ctx };
using key_t = Comparer::arg_t;
using val_t = int;
using map_t = std::map<key_t, val_t, Comparer>;
map_t mp{ comp };
}
另一个使用key std::pair的字符串或int进行搜索的示例
请注意,std::map不会使用等式lhs==rhs进行搜索,但会与小于和大于进行比较,因为它是经过排序的,这种方法会更快
另一方面,std::unordered\u映射使用散列程序(通常是std::hash)来测试相等性,因为它不是有序的。是的,您可以,std::map为您提供这些选项
假设您有std::map示例={{name1,1},{name2,id};//等等
使用“查找”搜索关键字,即字符串:
if (example.find("name2")!= example.end()) {
// Success
}
用于迭代地图并查找您的值:
for(const auto& itr : example){
if(itr.second == int_value) return true;
}
或者使用我为您制作的课程:
template<class T, class K, class value_compare = std::equal_to<K>, class key_compare = std::less<T> >
class MyMap : public std::map<T, K>
{
value_compare vc;
key_compare kc;
using my_iterator = typename std::map<T, K, key_compare>::iterator;
public:
my_iterator find_value(const K val) {
my_iterator itr = std::map<T, K>::begin();
my_iterator map_end = std::map<T, K>::end();
for (; itr != map_end; ++itr)
{
if (vc(itr->second, val)) return itr;
}
return itr;
}
};
你可能在寻找是的,这是可能的。您只需要实现一个能够高效地实现所有这些操作的自定义容器。听起来很有趣,祝你好运@山姆,我从哪里开始呢?有一个相当简单的方法来做这种事情。只需拿出一张白纸,用简单明了的英语写下简短的句子,这是一个循序渐进的过程。完成后。在你的橡皮鸭同意你提出的行动计划后,只需把你写下来的东西直接翻译成C++。任务完成了!你现在说的是,如果我说引入string1,1作为键,我将搜索string1或1,它将返回元素?我提供的示例允许你搜索字符串或int,而不是两者都可以在使用映射时进行切换。如果要同时搜索and和or结果,可以用相同的方法实现,并且可能不需要使用上下文。您甚至可以使用lambda作为比较方法!我不确定我是否知道如何在此中添加项目。。。我不太确定你在那里做了什么,你能再解释一下吗?还有,你怎样才能使它支持[]操作符?我不明白我该如何寻找他们?看到我的新例子了吗
template<class T, class K, class value_compare = std::equal_to<K>, class key_compare = std::less<T> >
class MyMap : public std::map<T, K>
{
value_compare vc;
key_compare kc;
using my_iterator = typename std::map<T, K, key_compare>::iterator;
public:
my_iterator find_value(const K val) {
my_iterator itr = std::map<T, K>::begin();
my_iterator map_end = std::map<T, K>::end();
for (; itr != map_end; ++itr)
{
if (vc(itr->second, val)) return itr;
}
return itr;
}
};
MyMap< std::string, int> ss_map;
ss_map["aab"] = 1;
ss_map["aba"] = 2;
ss_map["aaa"] = 3;
ss_map["abb"] = 4;
ss_map["baa"] = 5;
auto itr = ss_map.find("abb"); // return iterator<pair<"abb",4>>
auto itr2 = ss_map.find_value(2); // return iterator<pair<"aba",2>>