首页 文章

检查值存在于std :: map - C中

提问于
浏览
30

我知道find方法在std :: map中找到提供的键,并将迭代器返回给元素 . 反正有没有找到值并获得元素的迭代器?我需要做的是检查std :: map中是否存在指定的值 . 我通过循环 Map 中的所有项目并进行比较来完成此操作 . 但我想知道有没有更好的方法 .

这是我写的

bool ContainsValue(Type_ value)
{
    bool found = false;
    Map_::iterator it = internalMap.begin(); // internalMap is std::map
    while(it != internalMap.end())
    {
        found = (it->second == value);
        if(found)
            break;
        ++it;
    }
    return found;
}

Edit

如何在内部使用另一个存储值,键组合的 Map . 所以我可以打电话找到它吗?是std :: map中的find()进行顺序搜索吗?

谢谢

10 回答

  • 16

    您可以使用boost::multi_index创建bidirectional map - 您可以使用该对中的任意一个值作为快速查找的键 .

  • 6

    如果您可以访问优秀的boost库,那么您应该使用boost::multi_index创建bidirectional map,如Mark所说 . 与std :: map不同,它允许您通过键或值查找 .

    如果您只有STL,那么以下代码就可以实现(模板化可以使用mapped_type支持operator ==的任何类型的map):

    #include <map>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <cassert>
    
    template<class T>
    struct map_data_compare : public std::binary_function<typename T::value_type, 
                                                          typename T::mapped_type, 
                                                          bool>
    {
    public:
        bool operator() (typename T::value_type &pair, 
                         typename T::mapped_type i) const
        {
            return pair.second == i;
        }
    };
    
    
    int main()
    {
        typedef std::map<std::string, int> mapType;
    
        mapType map;
    
        map["a"] = 1;
        map["b"] = 2;
        map["c"] = 3;
        map["d"] = 4;
        map["e"] = 5;
    
        const int value = 3;
    
        std::map<std::string, int>::iterator it = std::find_if( map.begin(), map.end(), std::bind2nd(map_data_compare<mapType>(), value) );
    
        if ( it != map.end() )
        {
            assert( value == it->second);
            std::cout << "Found index:" << it->first << " for value:" << it->second << std::endl;
        }
        else
        {
            std::cout << "Did not find index for value:" << value << std::endl;
        }
    }
    
  • -3

    如何在内部使用另一个存储值,键组合的 Map . 所以我可以打电话找到它吗?

    是:维护两个 Map ,一个 Map 使用一种类型的密钥,另一个使用另一种 .

    std :: map中的find()是否进行顺序搜索?

    不,它是对已排序树的二进制搜索:其速度为O(log(n)) .

  • 0

    查看boost的双向映射:http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html

    它允许两个值都像一个键 .

    否则,迭代是要走的路 .

  • 1

    试试这个功能:

    template <class Map, class Val> typename Map::const_iterator MapSearchByValue(const Map & SearchMap, const Val & SearchVal)
    {
        Map::const_iterator iRet = SearchMap.end();
        for (Map::const_iterator iTer = SearchMap.begin(); iTer != SearchMap.end(); iTer ++)
        {
            if (iTer->second == SearchVal)
            {
                iRet = iTer;
                break;
            }
        }
        return iRet;
    }
    

    我觉得它很有用

  • 15

    不,你必须遍历std :: map并手动检查所有值 . 根据你想要做的事情,你可以将std :: map包装在一个简单的类中,该类也可以缓存插入到 Map 中的所有值,这些值很容易搜索并且不允许重复,比如std ::组 . 不要从std :: map继承(它没有虚拟析构函数!),但要包装它以便你可以这样做:

    WrappedMap my_map< std::string, double >;
    my_map[ "key" ] = 99.0;
    std::set< double > values = my_map.values(); // should give back a set with only 99.0 in it
    

    滚动自己的另一种选择是使用Boost双向 Map ,这可以在下面的帖子或Google中找到 .

    这实际上取决于你想做什么,你想要做多少次,以及滚动自己的小包装类与安装和使用Boost相比有多难 . 我喜欢Boost,所以这是一个很好的方法 - 但是有一些关于制作你自己的包装类的好东西和完整的东西 . 您可以直接了解操作的复杂性,并且可能不需要Boost双向映射提供的values =>键的完全反向映射 .

  • 2

    您要求的正是std::find所做的(不是成员函数)

    template< class InputIt, class T >
    InputIt find( InputIt first, InputIt last, const T& value );
    
  • 20

    不是一个非常好的选项,但在用户在初始化时分配默认值(如0或NULL)的少数情况下可能很有用 .

    Ex.
    < int , string >
    < string , int > 
    < string , string > 
    
    consider < string , string >
    mymap["1st"]="first";
    mymap["second"]="";
    for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    {
           if ( it->second =="" ) 
                continue;
    }
    
  • 0

    我正在添加这个答案,如果有人来这里寻找c 11及以上..

    //DECLARE A MAP
        std::map<int, int> testmap;
    
        //SAMPLE DATA
        testmap.insert(std::make_pair(1, 10));
        testmap.insert(std::make_pair(2, 20));
        testmap.insert(std::make_pair(3, 30));
        testmap.insert(std::make_pair(4, 20));
    
        //ELEMENTS WITH VALUE TO BE FOUND
        int value = 20;
    
        //RESULTS
        std::map<int, int> valuesMatching;
    
        //ONE STEP TO FIND ALL MATCHING MAP ELEMENTS
        std::copy_if(testmap.begin(), testmap.end(), std::inserter(valuesMatching, valuesMatching.end()), [value](const auto& v) {return v.second == value; });
    
  • 4

    可能我不想尝试完成 . 但是为了简单地测试一个 Map 是否包含一个值,我相信你可以使用 std::map 内置的 find .

    bool ContainsValue(Type_ value)
    {
        return (internalMap.find(value) != internalMap.end());
    }
    

相关问题