C++ Coding Reference: count and count_if

  • 时间:2020-09-17 14:37:27
  • 分类:网络文摘
  • 阅读:147 次

Novice C++ programmers usually write a simple for loop if they want to count number of particular elements in the array – which could be entirely replaced by STL::count or STL::count_if.

std::count()

For example, given the following vector/array.

1
vector<int> nums({ 1, 2, 3, 4, 5, 3});
vector<int> nums({ 1, 2, 3, 4, 5, 3});

If we want to count the number of 3’s, we can use the std::count(). The first two parameters of the count() specify the range of the vector, and the third parameter is the target element.

1
cout << count(begin(nums), end(nums), 3); // prints 2.
cout << count(begin(nums), end(nums), 3); // prints 2.

The count() is defined in C++ header xutility and has the following template definitions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// FUNCTION TEMPLATE count
template<class _InIt,
    class _Ty>
    _NODISCARD inline _Iter_diff_t<_InIt> count(const _InIt _First, const _InIt _Last, const _Ty& _Val)
    {   // count elements that match _Val
    _Adl_verify_range(_First, _Last);
    auto _UFirst = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    _Iter_diff_t<_InIt> _Count = 0;
 
    for (; _UFirst != _ULast; ++_UFirst)
        {
        if (*_UFirst == _Val)
            {
            ++_Count;
            }
        }
 
    return (_Count);
    }
 
#if _HAS_CXX17
template<class _ExPo,
    class _FwdIt,
    class _Ty,
    _Enable_if_execution_policy_t<_ExPo> = 0>
    _NODISCARD inline _Iter_diff_t<_FwdIt> count(_ExPo&& _Exec,
        const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val) noexcept;
#endif /* _HAS_CXX17 */
// FUNCTION TEMPLATE count
template<class _InIt,
	class _Ty>
	_NODISCARD inline _Iter_diff_t<_InIt> count(const _InIt _First, const _InIt _Last, const _Ty& _Val)
	{	// count elements that match _Val
	_Adl_verify_range(_First, _Last);
	auto _UFirst = _Get_unwrapped(_First);
	const auto _ULast = _Get_unwrapped(_Last);
	_Iter_diff_t<_InIt> _Count = 0;

	for (; _UFirst != _ULast; ++_UFirst)
		{
		if (*_UFirst == _Val)
			{
			++_Count;
			}
		}

	return (_Count);
	}

#if _HAS_CXX17
template<class _ExPo,
	class _FwdIt,
	class _Ty,
	_Enable_if_execution_policy_t<_ExPo> = 0>
	_NODISCARD inline _Iter_diff_t<_FwdIt> count(_ExPo&& _Exec,
		const _FwdIt _First, const _FwdIt _Last, const _Ty& _Val) noexcept;
#endif /* _HAS_CXX17 */

std::count_if()

What if you are looking to count something more complex e.g. the even numbers in the array/vector. We can use the std::count_if() which the third parameter is the specified predicate condition – you can pass in a lambda function.

1
2
3
4
vector<int> nums({ 1, 2, 3, 4, 5, 3});
cout << count_if(begin(nums), end(nums), [](auto &a) { 
   return a % 2 == 0; 
});  // print 2 because there are 2 even numbers: 2 and 4.
vector<int> nums({ 1, 2, 3, 4, 5, 3});
cout << count_if(begin(nums), end(nums), [](auto &a) { 
   return a % 2 == 0; 
});  // print 2 because there are 2 even numbers: 2 and 4.

The std::count_if is defined in C++ header file algorithm and its definition based on template is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// FUNCTION TEMPLATE count_if
template<class _InIt,
    class _Pr>
    _NODISCARD inline _Iter_diff_t<_InIt> count_if(_InIt _First, _InIt _Last, _Pr _Pred)
    {   // count elements satisfying _Pred
    _Adl_verify_range(_First, _Last);
    auto _UFirst = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    _Iter_diff_t<_InIt> _Count = 0;
    for (; _UFirst != _ULast; ++_UFirst)
        {
        if (_Pred(*_UFirst))
            {
            ++_Count;
            }
        }
 
    return (_Count);
    }
 
#if _HAS_CXX17
template<class _ExPo,
    class _FwdIt,
    class _Pr,
    _Enable_if_execution_policy_t<_ExPo> = 0>
    _NODISCARD inline _Iter_diff_t<_FwdIt> count_if(_ExPo&& _Exec,
        const _FwdIt _First, const _FwdIt _Last, _Pr _Pred) noexcept;
#endif /* _HAS_CXX17 */
// FUNCTION TEMPLATE count_if
template<class _InIt,
	class _Pr>
	_NODISCARD inline _Iter_diff_t<_InIt> count_if(_InIt _First, _InIt _Last, _Pr _Pred)
	{	// count elements satisfying _Pred
	_Adl_verify_range(_First, _Last);
	auto _UFirst = _Get_unwrapped(_First);
	const auto _ULast = _Get_unwrapped(_Last);
	_Iter_diff_t<_InIt> _Count = 0;
	for (; _UFirst != _ULast; ++_UFirst)
		{
		if (_Pred(*_UFirst))
			{
			++_Count;
			}
		}

	return (_Count);
	}

#if _HAS_CXX17
template<class _ExPo,
	class _FwdIt,
	class _Pr,
	_Enable_if_execution_policy_t<_ExPo> = 0>
	_NODISCARD inline _Iter_diff_t<_FwdIt> count_if(_ExPo&& _Exec,
		const _FwdIt _First, const _FwdIt _Last, _Pr _Pred) noexcept;
#endif /* _HAS_CXX17 */

count() and count_if() are self explanatory which means you don’t need to even put comments. Using the std::count() and std::count_if() from the STL, you probably don’t need to write your own loop to count the elements in the STL containers anymore!

–EOF (The Ultimate Computing & Technology Blog) —

推荐阅读:
盛夏常饮枸杞菊花茶 保养眼睛功效强  西瓜虽好,但这九类人群不宜吃西瓜  保健酒乱象调查:为见效快违法添加伟哥  饮用蜂蜜水的最佳时间及注意事项  红枣维生素含量高 喝大枣水养肝排毒  黑木耳营养丰富对健康有五大好处  香蕉和橘子能起到解毒护肝的作用  吃葡萄、喝葡萄酒能帮助调节性功能  绿茶、红茶、青茶、黑茶、白茶和黄茶  奶茶多添加奶精 长期食用会引发心脏病 
评论列表
添加评论