计算地图中相同值的数量

时间:2011-04-01 18:55:46

标签: c++ map count

是否有任何命令可以计算地图中相同值的数量?

像:

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

或者我应该自己写一下,因为它不太难?

5 个答案:

答案 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重命名为更有意义的东西。