C++ Coding Reference: count and count_if

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

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) —

推荐阅读:
SQL Algorithm to Compute Shortest Distance in a Plane  How to Count Univalue Subtrees in a Binary Tree?  Have Writer’s Block? Try These Content Ideation Tools for Market  Quick Ways to Relax Once You’ve Hit Publish  How to Prepare Your SEO Strategy for the Internet of Things  Keep Yourself Safe: Social Media Strategies  7 Ways to Use Video on Your Blog to Get More Engagement  Should You Build Your Blog on a CMS or a Website Builder?  5 Top Tips on How to Be a Top Game Blogger  Blog Stalkers: Staying Safe Online 
评论列表
添加评论