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

发布于 2024-08-14 18:56:02 字数 1100 浏览 6 评论 0原文

我有一个 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() ;

我不确定这段代码是否可以编译。

I have an STL::multimap and which I search to populate a std::list with values where keys are duplicated.

Can I find/insert to a std::list the value of elements for all key where count > 1 without counting them one by one?

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 might contain "a" ,"c","j","k" ;

I try this

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

I'm not sure if this code compiles.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

玉环 2024-08-21 18:56:02

您使用 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" }

You use the equal_range method which returns a pair of iterators bounding the requested value then loop between the returned iterators. (Note the use of the typedef for brevity).

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 should now contain { "j", "k" }

抠脚大汉 2024-08-21 18:56:02

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

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

编辑:另外,“them”的先行词尚不清楚。我认为它是指与特定键关联的值。这与多重映射中的值总数相反。

edit2:从您回答问题的声音来看,您希望多重映射告诉您哪些值具有重复的键。没有办法做到这一点;如果不循环键,multimap 就无法提供您想要的功能。

如果您想要此功能,您应该考虑在将值插入多重映射时插入填充重复项列表...当然,仅在发现存在重复项时才插入它们。

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

Yes. Use the count() function. Please see the posted reference. But why worry about that? If there are duplicates, you'll have to iterate over them anyway to populate the list.

edit: also, the antecedant of "them" is unclear. I take it to mean the values associated with a specific key. This is opposed to the total number of values in the multimap.

edit2: from the sounds of how you are replying to questions, you want the multimap to tell you what values have duplicate keys. There is no way to do this; multimap doesn't provide the functionality you want without looping over your keys.

If you want this functionality, you should consider inserting populating your list of duplicates as you insert the values into the multimap... of course, only inserting them as you discover when there are duplicates.

饭团 2024-08-21 18:56:02

来源

#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" }

Source:

#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;
}

Output:

~/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" }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文