31

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

編集

値、キーの組み合わせを格納する別のマップを内部で使用するのはどうですか。だから私はそれでfindを呼び出すことができますか?std::map のfind()は順次検索を行っていますか?

ありがとう

4

10 に答える 10

20

boost::multi_indexを使用して双方向マップを作成できます。ペアのいずれかの値をキーとして使用して、すばやく検索できます。

于 2009-02-11T03:46:00.257 に答える
17

優れたブーストライブラリにアクセスできる場合は、Mark が言うように、 boost::multi_indexを使用して双方向マップを作成する必要があります。std::map とは異なり、これにより、キーまたは値のいずれかで検索できます。

手元に STL しかない場合は、次のコードでうまくいきます (mapped_type が operator== をサポートするあらゆる種類のマップで動作するようにテンプレート化されています)。

#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;
    }
}
于 2009-05-24T21:52:52.687 に答える
15

値、キーの組み合わせを格納する別のマップを内部で使用するのはどうですか。だから私はそれでfindを呼び出すことができますか?

はい: 2 つのマップを維持します。1 つのマップは 1 つのタイプのキーを使用し、もう 1 つは別のキーを使用します。

std::map の find() は順次検索を行っていますか?

いいえ、ソートされたツリーの二分探索です。速度は O(log(n)) です。

于 2009-02-11T03:53:55.930 に答える
6

ブーストの双方向マップを調べてください: http://www.boost.org/doc/libs/1_38_0/libs/bimap/doc/html/index.html

両方の値がキーのように機能します。

それ以外の場合は、反復が有効です。

于 2009-02-11T03:46:55.200 に答える
4

あなたが要求しているのは、まさにstd::findが行うことです(メンバー関数ではありません)

template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
于 2017-03-08T13:15:19.477 に答える
4

この機能を試してください:

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

便利だと思います

于 2011-07-13T19:21:39.987 に答える
2

いいえ、 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 双方向マップによって提供される値 => キーの完全な逆マッピングは必要ない場合があります。

于 2009-02-11T03:40:47.413 に答える
-3

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.

bool ContainsValue(Type_ value)
{
    return (internalMap.find(value) != internalMap.end());
}
于 2010-12-01T19:16:55.317 に答える