C++ 对无序映射STL搜索

C++ 对无序映射STL搜索,c++,dictionary,hashmap,C++,Dictionary,Hashmap,我想创建一个hashmap,我可以以某种方式搜索键的两个部分。假设我有一双鞋,我想把它作为钥匙。我不想搜索精确的{string,id},但有时搜索int,有时搜索字符串,这可能吗?是的,可能!然而,它不是很有用,而且设计很糟糕 解决方案是使用自定义比较类型,该类型将自定义比较操作。如果您想要比较器中的一个行为,那么您只需要一个自由上下文比较类型,它可以执行您想要的任何操作 但是,如果您想根据需要从映射外部更改行为,您将使用一个比较器,该比较器具有超出映射的上下文 struct CompareCo

我想创建一个hashmap,我可以以某种方式搜索键的两个部分。假设我有一双鞋,我想把它作为钥匙。我不想搜索精确的{string,id},但有时搜索int,有时搜索字符串,这可能吗?

是的,可能!然而,它不是很有用,而且设计很糟糕

解决方案是使用自定义比较类型,该类型将自定义比较操作。如果您想要比较器中的一个行为,那么您只需要一个自由上下文比较类型,它可以执行您想要的任何操作

但是,如果您想根据需要从映射外部更改行为,您将使用一个比较器,该比较器具有超出映射的上下文

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>>