簡體   English   中英

檢查值存在於std :: map - C ++中

[英]Checking value exist in a std::map - C++

我知道find方法在std :: map中找到提供的鍵,並將迭代器返回給元素。 反正有沒有找到值並獲得元素的迭代器? 我需要做的是檢查std :: 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;
}

編輯

如何在內部使用另一個存儲值,鍵組合的地圖。 所以我可以打電話找到它嗎? std :: map中的find()是否進行順序搜索?

謝謝

您可以使用boost :: multi_index創建雙向映射 - 您可以使用該對中的任意一個值作為快速查找的鍵。

如果您可以訪問優秀的boost庫,那么您應該使用boost :: multi_index來創建雙向映射,正如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;
    }
}

如何在內部使用另一個存儲值,鍵組合的地圖。 所以我可以打電話找到它嗎?

是:維護兩個地圖,一個地圖使用一種類型的密鑰,另一個地圖使用另一種。

std :: map中的find()是否進行順序搜索?

不,它是對已排序樹的二進制搜索:其速度為O(log(n))。

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

它讓兩個值都像一把鑰匙。

否則,迭代是要走的路。

試試這個功能:

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

我覺得它很有用

不,你必須遍歷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

滾動自己的另一種選擇是使用Boost雙向地圖,這可以在下面的帖子中找到,也可以通過Google找到。

這實際上取決於你想做什么,你想要做多少次,以及滾動你自己的小包裝類與安裝和使用Boost相比有多難。 我喜歡Boost,所以這是一個很好的方法 - 但是有一些關於制作你自己的包裝類的好東西和完整的東西。 您可以直接了解操作的復雜性,也可能不需要Boost雙向映射提供的values =>鍵的完全反向映射。

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

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

不是一個非常好的選項,但在用戶在初始化時分配默認值(如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;
}

我添加這個答案,如果有人來這里尋找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; });

可能我不完全明白你想要完成的事情。 但是為了簡單地測試一個地圖是否包含一個值,我相信你可以使用std::map的內置find

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM