2013-04-28 62 views
7

我使用的std ::地圖這樣的方式:C++的std ::地圖<的std :: string,int>的獲取值,其鍵開始與一個特定的字符串

#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」)似乎是這樣做的 – 2013-04-28 12:55:35

+0

爲什麼不能獲得「Ac」的界限? b和c之間沒有字母。 – stardust 2013-04-28 12:55:50

+0

我需要更一般的方法。例子只是爲了描述問題。我可以是任何類型的字符串,並且map可以包含任何類型的字符串。 – Dejwi 2013-04-28 12:58:12

回答

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 2013-04-28 13:42:16

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();