C++中的count和count_if

本文详细介绍了C++标准库中的count和count_if算法的实现原理与使用方法,通过具体示例展示了如何统计数组或容器中特定元素的数量。

1.实现源码与说明

1.1 源码  

/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/stl_algo.h

template <typename _InputIterator, typename _Tp>
inline typename iterator_traits<_InputIterator>::difference_type
count(_InputIterator __first, _InputIterator __last, const _Tp &__value)
{
    // concept requirements
    __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
        __glibcxx_function_requires(_EqualOpConcept<typename iterator_traits<_InputIterator>::value_type, _Tp>)
            __glibcxx_requires_valid_range(__first, __last);
    return std::__count_if(__first, __last, __gnu_cxx::__ops::__iter_equals_val(__value));
}

template <typename _InputIterator, typename _Predicate>
inline typename iterator_traits<_InputIterator>::difference_type
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{
    // concept requirements
    __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
        __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate, typename iterator_traits<_InputIterator>::value_type>)
            __glibcxx_requires_valid_range(__first, __last);

    return std::__count_if(__first, __last,__gnu_cxx::__ops::__pred_iter(__pred));
}

template <typename _InputIterator, typename _Predicate>
typename iterator_traits<_InputIterator>::difference_type
__count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{
    typename iterator_traits<_InputIterator>::difference_type __n = 0;
    for (; __first != __last; ++__first)
        if (__pred(__first))
            ++__n;
    return __n;
}

 1.2 说明

difference_type count(InputIterator beg, InputIterator end, const T& value)
difference_type count_if(InputIterator beg, InputIterator end, UnaryPredicate op)
第一形式计算区间[beg,end)中“元素值等于value”的元素个数;
第二形式计算区间[beg,end)中“令unary predicate op(elem)结果为true”的元素个数;

注释:
(1)返回类型difference_type,是用以表现iterator间距的类型:
   typename iterator_traits<InputIterator> ::difference_type, 
   在侯捷老师的《C++源码剖析》中有讲解到.
(2)op不应在函数调用过程中改变状态,见10.1.4节;
(3)op不应改动传入的实参;
(4)Associative和unordered容器提供了一个类似的成员函数count(),用来计算“以某给定值为key”的元
   素个数(见8.3.3节第404页);
(5)复杂度:线性,执行比较动作(或调用op())共numElems次.


2.示例

2.1 std::count

#include <iostream>     
#include <algorithm>    
#include <vector>       
 
int main() {
    // counting elements in array:
    int myints[] = { 10,20,30,30,20,10,10,20 };   
    int mycount = std::count(myints,   myints + 8    , 10);
    std::cout << "10 appears " << mycount << " times.\n";
 
    // counting elements in container:
    std::vector<int> myvector(myints,    myints + 8    );
    mycount = std::count(myvector.begin(), myvector.end(), 20);
    std::cout << "20 appears " << mycount << " times.\n";
 
    return 0;
}

 2.2 std::count_if

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
 
template<class T>
void init_value(T& vect, int first, int last)
{
	if (last > first)
	{
		for (int i = first; i <= last; ++i)
		{
			vect.insert(vect.end(), i);  //尾插
		}
	}
}
 
void Print(int elem)
{
	cout << elem << " ";
}
 
bool pred(int elem)
{
	return elem % 2 == 0;   //是否是偶数
}
 
void main()
{
	vector<int> myvector;
	init_value(myvector, 1, 10);
	for_each(myvector.begin(), myvector.end(), Print);
	cout << endl;
 
	int ct = count(myvector.begin(), myvector.end(), 4);  //统计等于 4 的数的个数
	int ct_if = count_if(myvector.begin(), myvector.end(), pred);  //统计偶数的个数
	int ct_if1 = count_if(myvector.begin(), myvector.end(), bind2nd(greater<int>(), 2)); //统计大于 2 的个数
	cout << "ct " << ct << endl;   // 1
	cout << "ct_if " << ct_if << endl;  // 5
	cout << "ct_if1  " << ct_if1 << endl;  // 8
}

2.3 书上的例子

#include "algostuff.hpp"
using namespace std;

int main()
{
    vector<int> coll;
    int num;
    INSERT_ELEMENTS(coll,1,9);
    PRINT_ELEMENTS(coll,"coll: ");

    // count elements with value 4
    num = count (coll.cbegin(), coll.cend(),     // range
                 4);                             // value
    cout << "number of elements equal to 4:      " << num << endl;

    // count elements with even value
    num = count_if (coll.cbegin(), coll.cend(),  // range
                    [](int elem){                // criterion
                        return elem%2==0;
                    });
    cout << "number of elements with even value: " << num << endl;

    // count elements that are greater than value 4
    num = count_if (coll.cbegin(), coll.cend(),  // range
                    [](int elem){                // criterion
                        return elem>4;
                    });
    cout << "number of elements greater than 4:  " << num << endl;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值