C++ Algorithm Count: std::count, count_if, all_of, any_of & none_of

C++ Algorithm Count: std::count, count_if, all_of, any_of & none_of

이 글의 핵심

Practical guide to C++ counting and predicate algorithms on ranges.

Introduction

Counting algorithms count elements or test predicates over a range: count, count_if, all_of, any_of, and none_of.


1. count

Basic use

#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> v = {1, 2, 3, 2, 4, 2, 5};
    
    int count = std::count(v.begin(), v.end(), 2);
    
    std::cout << "Count of 2: " << count << std::endl;
    
    return 0;
}

On strings

#include <algorithm>
#include <string>
#include <iostream>

int main() {
    std::string text = "hello world";
    
    int count = std::count(text.begin(), text.end(), 'l');
    
    std::cout << "Count of 'l': " << count << std::endl;
    
    return 0;
}

2. count_if

Conditional counting

#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;
    });
    
    int greaterThan5 = std::count_if(v.begin(), v.end(),  {
        return x > 5;
    });
    
    return 0;
}

With structs

#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}
    };
    
    int highScores = std::count_if(students.begin(), students.end(),
         {
            return s.score >= 90;
        });
    
    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;
    });
    
    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;
    });
    
    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;
    });
    
    return 0;
}

4. Common pitfalls

Empty range

#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> empty;
    
    int count = std::count(empty.begin(), empty.end(), 5);
    
    bool all = std::all_of(empty.begin(), empty.end(),  { return x > 0; });
    
    bool any = std::any_of(empty.begin(), empty.end(),  { return x > 0; });
    
    bool none = std::none_of(empty.begin(), empty.end(),  { return x < 0; });
    
    return 0;
}

Return type

#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    
    auto count = std::count(v.begin(), v.end(), 3);
    
    size_t count2 = std::count(v.begin(), v.end(), 3);
    
    return 0;
}

Short-circuit evaluation

#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;
    
    bool hasEven = std::any_of(v.begin(), v.end(), [&checks](int x) {
        ++checks;
        std::cout << "check: " << x << std::endl;
        return x % 2 == 0;
    });
    
    return 0;
}

Performance: multiple passes

#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;
    }
    
    return 0;
}

5. Example: statistics utility

#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 << "No data" << 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;
        
        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 << "=== Statistics ===" << std::endl;
        std::cout << "Count: " << count << std::endl;
        std::cout << "Sum: " << sum << std::endl;
        std::cout << "Mean: " << mean << std::endl;
        std::cout << "Min: " << *minIt << std::endl;
        std::cout << "Max: " << *maxIt << std::endl;
        std::cout << "Even: " << evenCount << ", Odd: " << oddCount << std::endl;
        std::cout << "Positive: " << positive << ", Negative: " << negative << ", Zero: " << 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;
        });
        
        bool noZero = std::none_of(data.begin(), data.end(),  {
            return x == 0;
        });
        
        std::cout << "\n=== Validation ===" << std::endl;
        std::cout << "All positive: " << std::boolalpha << allPositive << std::endl;
        std::cout << "Has negative: " << std::boolalpha << hasNegative << std::endl;
        std::cout << "No zero: " << 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 << "\nRange [1, 10]: " << std::boolalpha 
              << Statistics::inRange(data, 1, 10) << std::endl;
    
    std::cout << "Range [1, 5]: " << std::boolalpha 
              << Statistics::inRange(data, 1, 5) << std::endl;
    
    return 0;
}

6. Comparison

Signatures

#include <algorithm>

Comparison table

AlgorithmReturnTimeShort-circuitEmpty range
countdifference_typeO(n)No0
count_ifdifference_typeO(n)No0
all_ofboolO(n)Yestrue
any_ofboolO(n)Yesfalse
none_ofboolO(n)Yestrue

Summary

  1. count: occurrences of a value
  2. count_if: count of predicate matches
  3. all_of / any_of / none_of: boolean tests with short-circuiting
  4. Time: O(n) for all

Choosing an algorithm

GoalAlgorithmExample
Count valuecountcount(v.begin(), v.end(), 5)
Count predicatecount_ifcount_if(v.begin(), v.end(), isEven)
All satisfyall_ofall_of(v.begin(), v.end(), isPositive)
Any satisfiesany_ofany_of(v.begin(), v.end(), isNegative)
None satisfynone_ofnone_of(v.begin(), v.end(), isZero)

Next steps

  • C++ Algorithm Remove
  • C++ Algorithm Sort

  • C++ STL algorithm basics