2009-12-13 73 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