2013-04-28 10 views
7

そのキーを開始し、特定の文字列を取得値:C++のstd ::マップ<はstd ::文字列、整数>私は、このような方法でのstd ::マップを使用してい

#include <map> 
#include <string> 
#include <iostream> 

using namespace std; 

int main(int argc, char* argv[]) 
{ 
    map<string, int> my_map; 

    my_map.insert(pair<string, int>("Ab", 1)); 
    my_map.insert(pair<string, int>("Abb", 2)); 
    my_map.insert(pair<string, int>("Abc", 3)); 
    my_map.insert(pair<string, int>("Abd", 4)); 
    my_map.insert(pair<string, int>("Ac", 5)); 
    my_map.insert(pair<string, int>("Ad", 5)); 

    cout<<my_map.lower_bound("Ab")->second<<endl; 
    cout<<my_map.upper_bound("Ab")->second<<endl; 
    return 0; 
} 

http://ideone.com/5YPQmj

キーが特定の文字列(たとえば "Ab")で始まるすべての値を取得したいと思います。 map :: lower_boundを使用してイテレータを簡単に開始できます。しかし、どうすれば上限を得ることができますか?下限から始まってセット全体を反復して、 "Ab"で始まるすべてのキーをチェックする必要がありますか?

+2

この特定のケースでは、my_map.lower_bound( "Ac")はそれを行うようです –

+0

"Ac"の境界線を取得できませんか? bとcの間に手紙はありません。 – stardust

+0

私はより一般的なアプローチが必要です。例は問題を説明することに過ぎませんでした。私はどんな種類の文字列でも構いません。マップにはあらゆる種類の文字列を含めることができます。 – Dejwi

答えて

1

私は同様の答えは、このページをチェックアウトが見つかりました:(map complex find operation

コード発揮:

template<typename Map> typename Map::const_iterator 
find_prefix(Map const& map, typename Map::key_type const& key) 
{ 
    typename Map::const_iterator it = map.upper_bound(key); 
    while (it != map.begin()) 
    { 
     --it; 
     if(key.substr(0, it->first.size()) == it->first) 
      return it; 
    } 

    return map.end(); // map contains no prefix 
} 

この例では、あなたが探して初めまで後方UPPER_BOUNDから繰り返すかのように見えます特定のサブ

この例はわずかに異なっているはずですが良いビルディングブロックとしてサーバー

+0

これは非常に最適ではない解決策であり、別のデータ構造が順調であると言及する必要があります。 – sehe

1
class BeginWithKey 
{ 
public: 
    BeginWithKey(const string key); 
    bool operator()(const string& s,const int x); 
private: 
    const string& key_; 
}; 

BeginWithKey::BeginWithKey(const string key):key_(key) 
{ 
} 

bool BeginWithKey::operator()(const string& s, const int& rh) 
{ 
    bool begin = true; 

    for(int i = 0; i < key_.size() && begin; ++i) 
     begin = (s[i] == key_[i]); 
    return !begin; 
} 

int main() 
{ 
    //your code 

    //copying the map object 
    map<string, int> copy = my_map; 

    //removing the strings not beginning with abc 
    BeginWithKey func("abc"); 
    remove_if(copy.begin(), copy.end(), func); 

    return 0; 
} 

コードは任意の文字列キーで動作します。

1

あなたはあなたを与えるBoost filter iteratorは、「開始」を使用することができ、それらは述語(含める値と言うブール機能)例えば

与えられたとき、通常のイテレータからイテレータを「終了」:

template <class Predicate> 
boost::filter_iterator<Predicate, map<string,int>::const_iterator> begin(Predicate predicate) const 
{ 
    return boost::make_filter_iterator(predicate, my_map.begin(), my_map.end()); 
} 
template <class Predicate> 
boost::filter_iterator<Predicate, map<string,int>::const_iterator> end(Predicate predicate) const 
{ 
    return boost::make_filter_iterator(predicate, my_map.end(), my_map.end()); 
} 

struct isMatch 
{ 
    isMatch(const std::string prefix) {m_prefix = prefix;}; 
    bool operator()(std::string value) 
    { 
     return value.find_first_of(m_prefix) == 0; 
    }; 
    std::string m_prefix; 
}; 

//using: 
isMatch startWithAb("Ab"); 
auto myBegin = boost::filter_iterator<startWithAb> begin(); 
auto myEnd = boost::filter_iterator<startWithAb> end(); 
関連する問題