----------------
title : C++ 레퍼런스 - count 와 count_if 함수 (<algorithm>)
cat_title : count, count_if
ref_title : count, std::count, count_if, std::count_if
path : /C++ Reference/algorithm
publish_date : 2019-02-01
----------------

##@ cpp-ref-start

#@ count, count_if

`<algorithm>` 에 정의됨

```cpp-formatted
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type count(
  InputIterator first, InputIterator last, const T& val);

template <class ExecutionPolicy, class ForwardIt, class UnaryPredicate>
typename iterator_traits<ForwardIt>::difference_type count_if(
  ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryPredicate p);
```

범위 안의 원소들 중 특정 값(`count`) 과 일치하거나 특정 조건을 만족하는 원소(`count_if`)의 개수를 센다.

#### count

범위 안 (`first` 부터 `last` 전 까지) 의 원소들 중 `val` 과 일치하는 원소들의 개수를 셉니다. 이 때 원소를 비교하기 위해 `operator==` 를 사용합니다.

#### count_if

범위 안 (`first` 부터 `last` 전 까지) 의 원소들 중 `p` 가 참을 리턴하는 원소들의 개수를 셉니다. 다시 말해 원소 `e` 에 대해 `p(e)` 를 실행하였을 때, 참을 리턴하는 원소들의 개수를 셉니다.

### 인자들

* `first, last` : 원소들의 시작과 끝을 가리키는 반복자들. 이 때 확인하는 범위는 `[first, last)` 로 정의됩니다. `first` 가 가리키는 원소는 포함되지만 `last` 가 가리키는 원소는 포함되지 않습니다.
* `val` : 비교할 값. 이 때 `val` 의 타입 T 의 경우 `operator==` 가 정의되어 있어야만 합니다.
* `p` : 원소를 한 개만 가지는 단항 함수로 `p` 의 리턴값은 `bool` 로 변환 가능해야만 합니다. 이 때, `p` 는 원소를 변경하면 안됩니다.

### 리턴값

`val` 과 일치하거나 조건을 만족하는 원소의 개수를 리턴합니다. 리턴 타입은 `iterator_traits<InputIterator>::difference_type` 로 보통 부호 있는 정수 타입입니다.

### 구현 예시

#### count

```cpp-formatted
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type count(
  InputIterator first, InputIterator last, const T& val) {
  typename iterator_traits<InputIterator>::difference_type ret = 0;
  while (first != last) {
    if (*first == val) ++ret;
    ++first;
  }
  return ret;
}
```

#### count_if

```cpp-formatted
template <class InputIt, class UnaryPredicate>
typename iterator_traits<InputIt>::difference_type count_if(InputIt first,
                                                            InputIt last,
                                                            UnaryPredicate p) {
  typename iterator_traits<InputIt>::difference_type ret = 0;
  for (; first != last; ++first) {
    if (p(*first)) {
      ret++;
    }
  }
  return ret;
}
```

### 실행 예제

```cpp-formatted
#include <algorithm>  // std::count
#include <iostream>   // std::cout
#include <vector>     // std::vector

int main() {
  // 배열 안의 특정 원소 개수를 셉니다.
  int myints[] = {10, 20, 30, 30, 20, 10, 10, 20};  // 8 elements
  int mycount = std::count(myints, myints + 8, 10);
  std::cout << "10 은 " << mycount << " 번 등장합니다.\n";

  // 컨테이너 안에 특정 원소의 개수를 셉니다.
  std::vector<int> myvector(myints, myints + 8);
  mycount = std::count(myvector.begin(), myvector.end(), 20);
  std::cout << "20 은 " << mycount << " 번 등장합니다.\n";

  // 20 이하의 원소들의 개수를 셉니다.
  int under_20 = std::count_if(myvector.begin(), myvector.end(),
                            [](int elem) { return elem <= 20; });
  std::cout << "20 이하의 원소 개수는 " << under_20 << " 이다.\n";
  return 0;
}
```

실행 결과

```exec
10 은 3 번 등장합니다.
20 은 3 번 등장합니다.
20 이하의 원소 개수는 6 이다.
```

### 참고 자료

* `for_each` : 범위 안에 원소들 각각에 대해 전달된 함수를 호출한다.
* `find$algorithm` : 범위 안에 원소들 중 **값**이 일치하는 원소를 찾는다.