是否有任何命令可以计算地图中相同值的数量?
像:
map<int, string> m;
m[1] = "A";
m[22] = "A";
m[53] = "C";
m[12] = "A";
m[6] = "A";
int count = m.count("A");// 4
或者我应该自己写一下,因为它不太难?
答案 0 :(得分:14)
您可以将count_if
算法与自定义谓词函数对象一起使用:
template <typename Pair>
struct second_equal_to
: std::unary_function<const Pair&, bool>
{
second_equal_to(const typename Pair::second_type& value)
: value_(value) { }
bool operator()(const Pair& p) const
{
return p.second == *value_;
}
private:
typename Pair::second_type value_;
};
用法:
typedef std::map<int, std::string> Map;
typedef Map::value_type MapEntry;
std::count_if(m.begin(), m.end(), second_equal_to<MapEntry>("A"));
或者,对于更通用的解决方案,您可以编写apply_to_second
谓词变换器:
template <typename Pair, typename Predicate>
struct apply_to_second_f
: std::unary_function<const Pair&, bool>
{
apply_to_second_f(const Predicate& p)
: predicate_(p) { }
bool operator()(const Pair& p) const
{
return predicate_(p.second);
}
Predicate predicate_;
};
template <typename Pair, typename Predicate>
apply_to_second_f<Pair, Predicate> apply_to_second(const Predicate& p)
{
return apply_to_second_f<Pair, Predicate>(p);
}
用法:
std::count_if(m.begin(), m.end(),
apply_to_second<MapEntry>(std::bind2nd(std::equal_to<std::string>(), "A")));
如果您有一个支持lambda表达式的编译器,则根本不需要任何自定义谓词仿函数;你可以使用更简单的lambda:
std::count_if(m.begin(), m.end(), [](const MapEntry& e) {
return e.second == "A";
});
答案 1 :(得分:5)
您可以将std::count
与自定义值参数一起使用:
struct Compare {
std::string str;
Compare(const std::string& str) : str(str) {}
};
bool operator==(const std::pair<int, std::string>&p, const Compare& c) {
return c.str == p.second;
}
bool operator==(const Compare& c, const std::pair<int, std::string>&p) {
return c.str == p.second;
}
int main() {
std::map<int, std::string> m;
m[1] = "A";
m[22] = "A";
m[53] = "C";
m[12] = "A";
m[6] = "A";
int count = std::count(m.begin(), m.end(), Compare("A"));
std::cout << count << "\n";
}
答案 2 :(得分:2)
STL的count_if并且手动非常可行。
编辑:抱歉应该是count_if不计算
答案 3 :(得分:0)
map :: count是计算键而不是元素,所以你问题中的例子是错误的。您可能需要考虑使用额外的地图来跟踪每个值的计数。
map<string, int> value_count;
// use like this
++value_count[val];
答案 4 :(得分:0)
这应该是通用的:
template< class T1, class T2 >
class Condition
{
public:
Condition( const T2& val ) : _val( val ) {};
bool operator()( const typename std::pair< const T1, T2 >& aPair )
{
return (aPair.second == _val);
}
private:
const T2 _val;
};
然后你可以像这样使用它:
Condition< int, std::string > comp( "A" );
size_t count = std::count_if( m.begin(), m.end(), comp );
请注意,这与以前的答案并没有什么不同,但它应该可以重复使用迭代对的任何东西。只需将Condition重命名为更有意义的东西。