2009-12-13 76 views
1

我有一個STL::multimap,我搜索的是用複製密鑰的值填充std::listC++從std :: multimap中找到多個鍵

我可以找到/插入到std::list所有密鑰的元素的值,而count > 1沒有對它們逐一計數嗎?

std::multimap<int, std::string> mm ; 
mm[0] = "a" ; 
mm[1] = "b" ; 
mm[0] = "c" ; 
mm[2] = "j" ; 
mm[2] = "k" ; 


std::list<std::string> lst ; 

lst可能包含"a" ,"c","j","k";

我試試這個

template <class K, class V> 
class extract_value { 
private: 
    K last_key_ ; 
    std::list<V> m_list_value ; 
    std::pair<K, V> first_elem ; 
public: 
extract_value(const K& k_): last_key_(k_) { } 
void operator() (std::pair<const K, V> elem) 
{ 
    if (last_key_ == elem.first) 
    { 
    m_list_value.push_back(elem.second) ; 
    } 
    else 
    { 
    // First entry 
    last_key_ = elem.first; 
    first_elem= elem ; 
    } 
} 
std::list<V> get_value() { return m_list_value ; } 
}; 

ex_ = for_each(mm.begin(),mm.end(), extract_value<int, std::string>(0)) ; 
std::list<std::string> lst = ex_.get_value() ; 

我不知道如果這個代碼編譯。

+3

您可能要問一個實際的問題。 – Joe 2009-12-13 23:32:51

回答

0

http://www.cplusplus.com/reference/stl/multimap/

是。使用count()函數。請參閱發佈的參考。但爲什麼要擔心呢?如果有重複,則必須遍歷它們以填充列表。

編輯:另外,「他們」的antecedant不清楚。我認爲它是指與特定鍵相關的值。這與multimap中的值的總數相反。

edit2:從你如何回答問題的聲音中,你想讓multimap告訴你什麼值有重複的鍵。沒有辦法做到這一點;如果沒有循環使用密鑰,multimap不會提供您想要的功能。

如果你想要這個功能,你應該考慮插入填充你的重複列表,當你將值插入到multimap ...當然,只有當你發現有重複時纔會插入它們。

+0

對不起,我英文很差。 我想從地圖中提取所有值,如: std :: list values = myMap.getValueList(); 但只適用於重複密鑰。 – sch0ck9 2009-12-14 00:16:53

4

您使用equal_range方法,該方法返回一對限制請求值的迭代器,然後在返回的迭代器之間循環。 (爲了簡潔起見,請注意使用typedef)。

typedef std::multimap<int, std::string> int_str_mm_t; 
std::pair<int_str_mm_t::iterator, int_str_mm_t::iterator> range; 

range = mm.equal_range(2); 

for (int_str_mm_t::iterator it = range.first; it != range.second; ++it) 
{ 
    lst.push_back(it->second); 
} 

LST現在應該包含{ 「J」, 「K」}

+0

我不希望只有密鑰2的值,但密鑰重複的所有值:「a」,「c」,「j」,「k」 – sch0ck9 2009-12-13 23:57:20

+0

您將首先需要檢測(或提取)重複值。這可以通過在上面的代碼中進行循環來完成,該代碼遍歷每個元素中的mm比較,調用equal_range並計算返回的兩個迭代器之間的元素數量。使用標題中的功能對象和方法執行此操作有更復雜但更優雅的方法(請參閱http://msdn.microsoft.com/zh-cn/library/yah1y2x8(VS.80))。aspx) – mcdave 2009-12-14 00:14:04

+0

即使你的回答沒有幫助問這個問題的人,它幫助我弄清楚如何從一個單一的鍵獲得一系列值。謝謝! – leetNightshade 2012-02-22 22:22:19

0

來源

#include <iostream> 
#include <cstdlib> 

#include <map> 
#include <list> 
#include <iterator> 

typedef int      Key; 
typedef std::string    Value; 
typedef std::multimap<Key,Value> Map; 
typedef std::list<Value>   List; 

std::ostream& operator<<(std::ostream& o, const Map& map) 
{ 
    for (Map::const_iterator it = map.begin(); it != map.end(); ++it) 
    o << "map[" << it->first << "] = \"" << it->second << "\"" << std::endl; 

    return o; 
} 

std::ostream& operator<<(std::ostream& o, const List& list) 
{ 
    o << "list = { "; 
    for (List::const_iterator it=list.begin(); it!=list.end(); ++it) 
    { 
    if (it!=list.begin()) 
     o << ", "; 
    o << "\"" << *it << "\""; 
    } 
    o << " }" << std::endl; 

    return o; 
} 

struct get_second : std::unary_function<Map::value_type, Value> 
{ 
    result_type operator()(argument_type i) 
    { 
    return i.second; 
    } 
}; 

List find_double_keys(const Map& map) 
{ 
    List result; 

    // Empty map, nothing to do 
    if (map.empty()) 
    return result; 

    Map::const_iterator it = map.begin(); 

    while (it != map.end()) 
    { 
    // Find range of equal values [it;last[ 
    Map::const_iterator last = ++Map::const_iterator(it); 
    while (last->first == it->first && last != map.end()) 
     ++last; 

    // Check the range is more than 1 element 
    if (last != ++Map::const_iterator(it)) 
    { 
     std::transform(it, last, std::back_inserter(result), get_second()); 
    } 

    // Terminate or continue 
    if (last != map.end()) 
     it = ++last; 
    else 
     return result; 
    } 

    return result; 
} 

int main(int, char**) 
{ 
    Map map; 
    List list; 

    map.insert(std::make_pair<Key,Value>(0,"a")); 
    map.insert(std::make_pair<Key,Value>(1,"b")); 
    map.insert(std::make_pair<Key,Value>(0,"c")); 
    map.insert(std::make_pair<Key,Value>(0,"d")); 
    map.insert(std::make_pair<Key,Value>(2,"j")); 
    map.insert(std::make_pair<Key,Value>(2,"k")); 

    std::cout << "map:" << std::endl << map; 

    list = find_double_keys(map); 

    std::cout << std::endl << "list:" << std::endl << list; 

    return EXIT_SUCCESS; 
} 

輸出

~/Projects > g++ test.cpp -o test && ./test 
map: 
map[0] = "a" 
map[0] = "c" 
map[0] = "d" 
map[1] = "b" 
map[2] = "j" 
map[2] = "k" 

list: 
list = { "a", "c", "d", "j", "k" } 
+0

這看起來非常像OP特別說的不需要的方式。 – 2009-12-14 02:39:16