我有一个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() ;
我不确定此代码是否会编译。
答案 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" }