检查 std::map 中存在的值 - C++

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/535317/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:50:33  来源:igfitidea点击:

Checking value exist in a std::map - C++

c++iteratorfindstdmap

提问by Navaneeth K N

I know findmethod finds the supplied key in std::mapand return an iterator to the element. Is there anyway to find the value and get an iterator to the element? What I need to do is to check specified value exist in std::map. I have done this by looping all items in the map and comparing. But I wanted to know is there any better approach for this.

我知道find方法在std::map 中找到提供的键并将迭代器返回到元素。无论如何要找到值并获得元素的迭代器?我需要做的是检查 std::map 中是否存在指定的值。我通过循环地图中的所有项目并进行比较来做到这一点。但我想知道有没有更好的方法来解决这个问题。

Here is what I have wrote

这是我写的

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

编辑

How about using another map internally which stores value,key combination. So I can call find on it? Is find()in std::map doing sequential search?

如何在内部使用另一个存储值、组合键的映射。所以我可以调用 find 吗?std::map 中的find()是否在进行顺序搜索?

Thanks

谢谢

采纳答案by Mark Ransom

You can use boost::multi_indexto create a bidirectional map- you can use either value of the pair as a key to do a quick lookup.

您可以使用boost::multi_index创建双向映射- 您可以使用该对的任一值作为键进行快速查找。

回答by CodeBuddy

If you have access to the excellent boostlibrary then you should be using boost::multi_indexto create bidirectional mapas Mark says. Unlike a std::map this allows you to look up by either the key or the value.

如果您可以访问优秀的boost库,那么您应该使用boost::multi_index来创建双向映射,如 Mark 所说。与 std::map 不同,这允许您通过键或值进行查找。

If you only have the STL to hand the following code will do the trick (templated to work with any kind of map where the mapped_type supports operator==):

如果您只有 STL 来处理以下代码,则可以使用以下代码(模板化为可用于任何类型的映射,其中映射类型支持操作符==):

#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;
    }
}

回答by ChrisW

How about using another map internally which stores value,key combination. So I can call find on it?

如何在内部使用另一个存储值、组合键的映射。所以我可以调用 find 吗?

Yes: maintain two maps, with one map using one type of key and the other using the other.

是:维护两张地图,一张地图使用一种类型的密钥,另一个使用另一种。

Is find() in std::map doing sequential search?

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

No it's a binary search of a sorted tree: its speed is O(log(n)).

不,它是排序树的二分搜索:它的速度是 O(log(n))。

回答by Evan Teran

Look into boost's bidirectional maps: http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html

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

It lets both values act like a key.

它让两个值都像一个键。

Otherwise, iteration is the way to go.

否则,迭代是要走的路。

回答by Mitch

try this function:

试试这个功能:

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

i think it's useful

我认为它很有用

回答by AKludges

What you are requesting is precisely what std::finddoes (not the member function)

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

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

回答by James Thompson

No, you have to loop over the std::map and check all values manually. Depending on what you want to do, you could wrap the std::map in a simple class that also caches all of the values that are inserted into the map in something that's easily search-able and doesn't allow duplicates, like a std::set. Don't inherit from the std::map (it doesn't have a virtual destructor!), but wrap it so that you can do something like this:

不,您必须遍历 std::map 并手动检查所有值。根据您想要做什么,您可以将 std::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

An alternative to rolling your own would be to use the Boost bidirectional map, which is easily found in the posts below or by Google.

滚动自己的另一种方法是使用 Boost 双向映射,它可以在下面的帖子中或通过 Google 轻松找到。

It really depends on what you want to do, how often you want to do it, and how hard it is to roll your own little wrapper class versus installing and using Boost. I love Boost, so that's a good way to go - but there's something nice and complete about making your own wrapper class. You have the advantage of understanding directly the complexity of operations, and you may not need the full reverse mapping of values => keys that's provided by the Boost bidirectional map.

这实际上取决于您想要做什么,您想要多久做一次,以及推出您自己的小包装类与安装和使用 Boost 的难度。我喜欢 Boost,所以这是一个很好的方法——但是制作你自己的包装类有一些很好的和完整的东西。您具有直接理解操作复杂性的优势,并且您可能不需要 Boost 双向映射提供的值 => 键的完全反向映射。

回答by user2761565

Not a very best option but might be useful in few cases where user is assigning default value like 0 or NULL at initialization.

不是最好的选择,但在用户在初始化时分配默认值(如 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;
}

回答by Pavan Chandaka

I am adding this answer, if someone come here and looks for c++11 and above..

我正在添加这个答案,如果有人来这里寻找 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; });

回答by Ternary

Possible that I don't fully understand what you're trying to accomplish. But to simply test whether or not a map contains a value, I believe you can use the std::map's built in find.

可能我不完全理解你想要完成的任务。但是要简单地测试地图是否包含值,我相信您可以使用std::map内置的find.

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