C++ Algorithm Count | "카운트 알고리즘" 가이드
이 글의 핵심
C++ Algorithm Count에 대한 실전 가이드입니다.
들어가며
카운트 알고리즘은 컨테이너의 요소를 세거나 조건을 검사하는 알고리즘입니다. count, count_if, all_of, any_of, none_of 등을 제공합니다.
1. count
기본 사용
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 2, 4, 2, 5};
// 2의 개수
int count = std::count(v.begin(), v.end(), 2);
std::cout << "2의 개수: " << count << std::endl; // 3
return 0;
}
문자열에서 사용
#include <algorithm>
#include <string>
#include <iostream>
int main() {
std::string text = "hello world";
// 'l'의 개수
int count = std::count(text.begin(), text.end(), 'l');
std::cout << "'l'의 개수: " << count << std::endl; // 3
return 0;
}
2. count_if
조건부 카운트
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 짝수 개수
int evenCount = std::count_if(v.begin(), v.end(), {
return x % 2 == 0;
});
std::cout << "짝수 개수: " << evenCount << std::endl; // 5
// 5보다 큰 수
int greaterThan5 = std::count_if(v.begin(), v.end(), {
return x > 5;
});
std::cout << "5보다 큰 수: " << greaterThan5 << std::endl; // 5
return 0;
}
구조체에서 사용
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
struct Student {
std::string name;
int score;
};
int main() {
std::vector<Student> students = {
{"Alice", 85},
{"Bob", 92},
{"Charlie", 78},
{"David", 95},
{"Eve", 88}
};
// 90점 이상
int highScores = std::count_if(students.begin(), students.end(),
{
return s.score >= 90;
});
std::cout << "90점 이상: " << highScores << "명" << std::endl; // 2명
return 0;
}
3. all_of, any_of, none_of
all_of (모두)
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v1 = {2, 4, 6, 8, 10};
std::vector<int> v2 = {2, 4, 5, 8, 10};
// 모두 짝수?
bool allEven1 = std::all_of(v1.begin(), v1.end(), {
return x % 2 == 0;
});
bool allEven2 = std::all_of(v2.begin(), v2.end(), {
return x % 2 == 0;
});
std::cout << "v1 모두 짝수: " << std::boolalpha << allEven1 << std::endl; // true
std::cout << "v2 모두 짝수: " << std::boolalpha << allEven2 << std::endl; // false
return 0;
}
any_of (하나라도)
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v1 = {1, 3, 5, 7, 9};
std::vector<int> v2 = {1, 3, 4, 7, 9};
// 하나라도 짝수?
bool hasEven1 = std::any_of(v1.begin(), v1.end(), {
return x % 2 == 0;
});
bool hasEven2 = std::any_of(v2.begin(), v2.end(), {
return x % 2 == 0;
});
std::cout << "v1 짝수 있음: " << std::boolalpha << hasEven1 << std::endl; // false
std::cout << "v2 짝수 있음: " << std::boolalpha << hasEven2 << std::endl; // true
return 0;
}
none_of (없음)
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 3, 5, 7, 9};
// 음수 없음?
bool noNegative = std::none_of(v.begin(), v.end(), {
return x < 0;
});
std::cout << "음수 없음: " << std::boolalpha << noNegative << std::endl; // true
return 0;
}
4. 자주 발생하는 문제
문제 1: 빈 범위
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> empty;
// count: 0
int count = std::count(empty.begin(), empty.end(), 5);
std::cout << "count: " << count << std::endl; // 0
// all_of: true (공허한 참)
bool all = std::all_of(empty.begin(), empty.end(), { return x > 0; });
std::cout << "all_of: " << std::boolalpha << all << std::endl; // true
// any_of: false
bool any = std::any_of(empty.begin(), empty.end(), { return x > 0; });
std::cout << "any_of: " << std::boolalpha << any << std::endl; // false
// none_of: true
bool none = std::none_of(empty.begin(), empty.end(), { return x < 0; });
std::cout << "none_of: " << std::boolalpha << none << std::endl; // true
return 0;
}
문제 2: 반환 타입
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// count 반환 타입: difference_type (보통 ptrdiff_t)
auto count = std::count(v.begin(), v.end(), 3);
// ✅ 명시적 타입
size_t count2 = std::count(v.begin(), v.end(), 3);
std::cout << "count: " << count << std::endl;
std::cout << "count2: " << count2 << std::endl;
return 0;
}
문제 3: 단락 평가
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int checks = 0;
// any_of: 첫 true에서 중단
bool hasEven = std::any_of(v.begin(), v.end(), [&checks](int x) {
++checks;
std::cout << "검사: " << x << std::endl;
return x % 2 == 0;
});
std::cout << "짝수 있음: " << std::boolalpha << hasEven << std::endl;
std::cout << "검사 횟수: " << checks << std::endl; // 2 (1, 2만 검사)
return 0;
}
출력:
검사: 1
검사: 2
짝수 있음: true
검사 횟수: 2
문제 4: 성능
#include <algorithm>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// ❌ 여러 번 순회
int even = std::count_if(v.begin(), v.end(), { return x % 2 == 0; });
int odd = std::count_if(v.begin(), v.end(), { return x % 2 != 0; });
int gt5 = std::count_if(v.begin(), v.end(), { return x > 5; });
// ✅ 한 번에 순회
int evenCount = 0, oddCount = 0, gt5Count = 0;
for (int x : v) {
if (x % 2 == 0) ++evenCount;
else ++oddCount;
if (x > 5) ++gt5Count;
}
std::cout << "짝수: " << evenCount << ", 홀수: " << oddCount
<< ", >5: " << gt5Count << std::endl;
return 0;
}
5. 실전 예제: 통계 유틸리티
#include <algorithm>
#include <vector>
#include <numeric>
#include <cmath>
#include <iostream>
class Statistics {
public:
// 기본 통계
static void analyze(const std::vector<int>& data) {
if (data.empty()) {
std::cout << "데이터 없음" << std::endl;
return;
}
// 개수
size_t count = data.size();
// 합계
int sum = std::accumulate(data.begin(), data.end(), 0);
// 평균
double mean = static_cast<double>(sum) / count;
// 최소/최대
auto [minIt, maxIt] = std::minmax_element(data.begin(), data.end());
// 짝수/홀수
int evenCount = std::count_if(data.begin(), data.end(), {
return x % 2 == 0;
});
int oddCount = count - evenCount;
// 양수/음수/0
int positive = std::count_if(data.begin(), data.end(), { return x > 0; });
int negative = std::count_if(data.begin(), data.end(), { return x < 0; });
int zero = std::count(data.begin(), data.end(), 0);
// 출력
std::cout << "=== 통계 ===" << std::endl;
std::cout << "개수: " << count << std::endl;
std::cout << "합계: " << sum << std::endl;
std::cout << "평균: " << mean << std::endl;
std::cout << "최소: " << *minIt << std::endl;
std::cout << "최대: " << *maxIt << std::endl;
std::cout << "짝수: " << evenCount << ", 홀수: " << oddCount << std::endl;
std::cout << "양수: " << positive << ", 음수: " << negative << ", 0: " << zero << std::endl;
}
// 조건 검사
static void validate(const std::vector<int>& data) {
// 모두 양수?
bool allPositive = std::all_of(data.begin(), data.end(), {
return x > 0;
});
// 하나라도 음수?
bool hasNegative = std::any_of(data.begin(), data.end(), {
return x < 0;
});
// 0 없음?
bool noZero = std::none_of(data.begin(), data.end(), {
return x == 0;
});
std::cout << "\n=== 검증 ===" << std::endl;
std::cout << "모두 양수: " << std::boolalpha << allPositive << std::endl;
std::cout << "음수 있음: " << std::boolalpha << hasNegative << std::endl;
std::cout << "0 없음: " << std::boolalpha << noZero << std::endl;
}
// 범위 검사
static bool inRange(const std::vector<int>& data, int min, int max) {
return std::all_of(data.begin(), data.end(), [min, max](int x) {
return x >= min && x <= max;
});
}
};
int main() {
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Statistics::analyze(data);
Statistics::validate(data);
std::cout << "\n범위 [1, 10]: " << std::boolalpha
<< Statistics::inRange(data, 1, 10) << std::endl; // true
std::cout << "범위 [1, 5]: " << std::boolalpha
<< Statistics::inRange(data, 1, 5) << std::endl; // false
return 0;
}
출력:
=== 통계 ===
개수: 10
합계: 55
평균: 5.5
최소: 1
최대: 10
짝수: 5, 홀수: 5
양수: 10, 음수: 0, 0: 0
=== 검증 ===
모두 양수: true
음수 있음: false
0 없음: true
범위 [1, 10]: true
범위 [1, 5]: false
6. 카운트 알고리즘 비교
함수 시그니처
#include <algorithm>
// count: 값 개수
template<class InputIt, class T>
typename iterator_traits<InputIt>::difference_type
count(InputIt first, InputIt last, const T& value);
// count_if: 조건 개수
template<class InputIt, class UnaryPredicate>
typename iterator_traits<InputIt>::difference_type
count_if(InputIt first, InputIt last, UnaryPredicate p);
// all_of: 모두 만족?
template<class InputIt, class UnaryPredicate>
bool all_of(InputIt first, InputIt last, UnaryPredicate p);
// any_of: 하나라도 만족?
template<class InputIt, class UnaryPredicate>
bool any_of(InputIt first, InputIt last, UnaryPredicate p);
// none_of: 모두 불만족?
template<class InputIt, class UnaryPredicate>
bool none_of(InputIt first, InputIt last, UnaryPredicate p);
비교 표
| 알고리즘 | 반환 타입 | 시간복잡도 | 단락 평가 | 빈 범위 |
|---|---|---|---|---|
| count | difference_type | O(n) | ❌ | 0 |
| count_if | difference_type | O(n) | ❌ | 0 |
| all_of | bool | O(n) | ✅ | true |
| any_of | bool | O(n) | ✅ | false |
| none_of | bool | O(n) | ✅ | true |
정리
핵심 요약
- count: 특정 값 개수
- count_if: 조건 만족 개수
- all_of: 모두 만족? (단락 평가)
- any_of: 하나라도 만족? (단락 평가)
- none_of: 모두 불만족? (단락 평가)
- 시간복잡도: 모두 O(n)
카운트 알고리즘 선택 가이드
| 목적 | 알고리즘 | 예시 |
|---|---|---|
| 특정 값 개수 | count | count(v.begin(), v.end(), 5) |
| 조건 만족 개수 | count_if | count_if(v.begin(), v.end(), isEven) |
| 모두 만족? | all_of | all_of(v.begin(), v.end(), isPositive) |
| 하나라도 만족? | any_of | any_of(v.begin(), v.end(), isNegative) |
| 모두 불만족? | none_of | none_of(v.begin(), v.end(), isZero) |
실전 팁
사용 원칙:
- 특정 값 개수는
count - 조건부 개수는
count_if - 검증은
all_of,any_of,none_of - 단락 평가 활용 (성능)
성능:
- 모두 O(n) 순회
any_of,all_of는 단락 평가 (조기 종료)- 여러 조건은 한 번에 순회
- 빈 범위 체크
주의사항:
- 빈 범위:
all_of는 true,any_of는 false - 반환 타입:
count는difference_type - 단락 평가:
any_of는 첫 true에서 중단 - 부작용 금지: predicate는 순수 함수
다음 단계
- C++ Algorithm Find
- C++ Algorithm Remove
- C++ Algorithm Sort
관련 글
- C++ STL 알고리즘 기초 완벽 가이드 | sort·find