C++ Coding Reference: count and count_if

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

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

推荐阅读:
7 Passive Income Ideas to Complement Your Blog  Funny YouTuber Creates Device to Shoot Facemasks To Your Face  YouTube’s New “Viewer Applause” Feature Provides Revenue for Blo  Taiwanese Instagram Grandparents Prove Blogging and Social Media  These Incredible Hologram Machines Could Change the Vlogging Gam  Prepare All Keyboard Warriors: A TikTok and Twitter Merger is Ab  Content Creation Platforms That Pay in Crypto  How to be like Elon Musk: An Influencer CEO  Your Simple Guide to Ultimate Technology Stack Every Blogger Nee  Recursive Algorithm to Encrypte a String 
评论列表
添加评论