C ++从std :: multimap中查找多个键

时间:2009-12-13 23:29:27

标签: c++ multimap

我有一个STL::multimap,我搜索其中std::list填充了重复键的值。

我可以在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 个答案:

答案 0 :(得分: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);
}

我现在应该包含{“j”,“k”}

答案 1 :(得分:0)

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

是。使用count()函数。请参阅发布的参考资料。但为什么要担心呢?如果存在重复项,则无论如何都必须迭代它们以填充列表。

编辑:同样,“他们”的初步不清楚。我把它用来表示与特定键相关的值。这与多图中的值总数相反。

edit2:根据您回答问题的方式,您希望multimap告诉您哪些值具有重复键。没有办法做到这一点;多图不会提供您想要的功能而无需循环键。

如果您需要此功能,则应考虑在将值插入多图时插入填充重复列表...当然,只有当您发现重复时才会插入它们。

答案 2 :(得分: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" }