C++ Algorithm MinMax | "Min/Max Algorithm" Guide

C++ Algorithm MinMax | "Min/Max Algorithm" Guide

이 글의 핵심

std::min, std::max, minmax_element: pairwise compares vs range scans—find extrema and iterator positions in C++ STL.

Finding extrema shows up everywhere (normalization, clipping, game AI, analytics). C++ splits this into pairwise helpers (min, max, minmax—including constexpr overloads) and range algorithms (min_element, max_element, minmax_element) that return iterators so you know where the extreme value lives, not only its value.

What is the MinMax algorithm?

The MinMax family covers both two-value comparisons and range scans. Use std::min/std::max when you have two scalars or objects; use *min_element when you need the position in a sequence (e.g. to erase or update that element).

#include <algorithm>

int a = 3, b = 5;

// Minimum
int minVal = std::min(a, b);  // 3

// Maximum
int maxVal = std::max(a, b);  // 5

// Both
auto [minV, maxV] = std::minmax(a, b);

Why is it useful?:

  • Simplicity: Find min/max without conditional statements
  • Safety: Type-safe comparisons
  • Performance: Optimized implementation
  • Convenience: Supports range search
// ❌ Manual comparison: complex
int minVal;
if (a < b) {
    minVal = a;
} else {
    minVal = b;
}

// ✅ std::min: concise
int minVal = std::min(a, b);

Types of MinMax Algorithms:

AlgorithmInputReturnTime Complexity
min(a, b)2 valuesMinimum valueO(1)
max(a, b)2 valuesMaximum valueO(1)
minmax(a, b)2 values{min, max}O(1)
min_element(begin, end)RangeIterator to minimumO(n)
max_element(begin, end)RangeIterator to maximumO(n)
minmax_element(begin, end)Range{min, max} iteratorsO(n)
clamp(v, lo, hi)Value, rangeClamped valueO(1)
// Value comparison
int minVal = std::min(3, 5);
int maxVal = std::max(3, 5);
auto [minV, maxV] = std::minmax(3, 5);

// Range search
std::vector<int> v = {3, 1, 4, 1, 5};
auto minIt = std::min_element(v.begin(), v.end());
auto maxIt = std::max_element(v.begin(), v.end());
auto [minIt2, maxIt2] = std::minmax_element(v.begin(), v.end());

// Range clamping
int clamped = std::clamp(150, 0, 100);  // 100

Basic Usage

#include <algorithm>
#include <vector>

std::vector<int> v = {3, 1, 4, 1, 5};

// Minimum element
auto minIt = std::min_element(v.begin(), v.end());
std::cout << "Minimum: " << *minIt << std::endl;  // 1

// Maximum element
auto maxIt = std::max_element(v.begin(), v.end());
std::cout << "Maximum: " << *maxIt << std::endl;  // 5

Practical Examples

Example 1: minmax_element

#include <algorithm>
#include <vector>

int main() {
    std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
    
    // Find min and max simultaneously
    auto [minIt, maxIt] = std::minmax_element(v.begin(), v.end());
    
    std::cout << "Minimum: " << *minIt << std::endl;  // 1
    std::cout << "Maximum: " << *maxIt << std::endl;  // 9
}

Example 2: Custom Comparison

#include <algorithm>
#include <vector>
#include <string>

struct Person {
    std::string name;
    int age;
};

int main() {
    std::vector<Person> people = {
        {"Alice", 25},
        {"Bob", 30},
        {"Charlie", 20}
    };
    
    // Find youngest by age
    auto youngest = std::min_element(people.begin(), people.end(),
        [](const Person& a, const Person& b) {
            return a.age < b.age;
        });
    
    std::cout << "Youngest: " << youngest->name << " (" << youngest->age << ")" << std::endl;
}

Example 3: Multiple Values

#include <algorithm>

int main() {
    // Find min/max among multiple values
    int minVal = std::min({3, 1, 4, 1, 5, 9});
    int maxVal = std::max({3, 1, 4, 1, 5, 9});
    
    std::cout << "Minimum: " << minVal << std::endl;  // 1
    std::cout << "Maximum: " << maxVal << std::endl;  // 9
}

Example 4: Clamp

#include <algorithm>

int main() {
    int value = 150;
    
    // Clamp value to range (C++17)
    int clamped = std::clamp(value, 0, 100);
    
    std::cout << "Clamped: " << clamped << std::endl;  // 100
    
    // Equivalent to min(max(value, low), high)
}

MinMax Algorithms

// Value comparison
std::min(a, b)
std::max(a, b)
std::minmax(a, b)

// Range search
std::min_element(begin, end)
std::max_element(begin, end)
std::minmax_element(begin, end)

// Range clamping (C++17)
std::clamp(value, low, high)

Common Issues

Issue 1: References

int a = 3, b = 5;

// min/max returns const reference
const int& minRef = std::min(a, b);

// ❌ Temporary object
// const int& minRef = std::min(3, 5);  // Dangling reference

// ✅ Use value
int minVal = std::min(3, 5);

Issue 2: Empty Range

std::vector<int> v;

// ❌ Empty range
// auto minIt = std::min_element(v.begin(), v.end());  // Undefined behavior

// ✅ Check first
if (!v.empty()) {
    auto minIt = std::min_element(v.begin(), v.end());
}

Issue 3: Multiple Values

// ❌ Nested calls
int minVal = std::min(std::min(a, b), c);

// ✅ initializer_list
int minVal = std::min({a, b, c});

Issue 4: Clamp Order

// clamp(value, low, high)
// Ensure low <= high

int value = 50;

// ❌ low > high
// int clamped = std::clamp(value, 100, 0);  // Undefined behavior

// ✅ low <= high
int clamped = std::clamp(value, 0, 100);

Usage Patterns

// 1. Find min/max
int minVal = std::min(a, b);
int maxVal = std::max(a, b);

// 2. Range search
auto minIt = std::min_element(v.begin(), v.end());

// 3. Range clamping
int clamped = std::clamp(value, 0, 100);

// 4. Reverse order
std::reverse(v.begin(), v.end());

Practical Patterns

Pattern 1: Statistical Calculation

#include <algorithm>
#include <vector>
#include <numeric>

struct Statistics {
    int min;
    int max;
    double average;
};

Statistics calculateStats(const std::vector<int>& data) {
    if (data.empty()) {
        return {0, 0, 0.0};
    }
    
    auto [minIt, maxIt] = std::minmax_element(data.begin(), data.end());
    int sum = std::accumulate(data.begin(), data.end(), 0);
    
    return {
        *minIt,
        *maxIt,
        static_cast<double>(sum) / data.size()
    };
}

// Usage
std::vector<int> scores = {85, 92, 78, 95, 88};
auto stats = calculateStats(scores);
std::cout << "Minimum: " << stats.min << '\n';      // 78
std::cout << "Maximum: " << stats.max << '\n';      // 95
std::cout << "Average: " << stats.average << '\n';  // 87.6

Pattern 2: Range Validation

#include <algorithm>

template<typename T>
bool inRange(T value, T low, T high) {
    return value >= low && value <= high;
}

template<typename T>
T clampToRange(T value, T low, T high) {
    return std::clamp(value, low, high);
}

// Usage
int score = 150;
if (!inRange(score, 0, 100)) {
    score = clampToRange(score, 0, 100);  // 100
}

Pattern 3: Normalization

#include <algorithm>
#include <vector>

std::vector<double> normalize(const std::vector<double>& data) {
    if (data.empty()) {
        return {};
    }
    
    auto [minIt, maxIt] = std::minmax_element(data.begin(), data.end());
    double minVal = *minIt;
    double maxVal = *maxIt;
    double range = maxVal - minVal;
    
    if (range == 0.0) {
        return std::vector<double>(data.size(), 0.5);
    }
    
    std::vector<double> result;
    result.reserve(data.size());
    
    for (double value : data) {
        result.push_back((value - minVal) / range);
    }
    
    return result;
}

// Usage
std::vector<double> data = {10.0, 20.0, 30.0, 40.0, 50.0};
auto normalized = normalize(data);
// Result: {0.0, 0.25, 0.5, 0.75, 1.0}

FAQ

Q1: What is min/max?

A: Compares two values and returns the minimum or maximum.

int minVal = std::min(3, 5);  // 3
int maxVal = std::max(3, 5);  // 5

Q2: What is min_element?

A: Returns the iterator to the minimum element in a range.

std::vector<int> v = {3, 1, 4, 1, 5};
auto minIt = std::min_element(v.begin(), v.end());
std::cout << *minIt << '\n';  // 1

Q3: What is minmax?

A: Returns both the minimum and maximum values simultaneously, reducing the number of comparisons.

auto [minV, maxV] = std::minmax(3, 5);
// minV = 3, maxV = 5

Q4: What is clamp?

A: Restricts a value to a specified range (C++17).

int clamped = std::clamp(150, 0, 100);  // 100

Q5: How to find min/max among multiple values?

A: Use an initializer_list.

int minVal = std::min({3, 1, 4, 1, 5});  // 1
int maxVal = std::max({3, 1, 4, 1, 5});  // 5

Q6: What about empty ranges?

A: Undefined behavior. Always check for emptiness first.

std::vector<int> v;

// ❌ Empty range
// auto minIt = std::min_element(v.begin(), v.end());

// ✅ Check first
if (!v.empty()) {
    auto minIt = std::min_element(v.begin(), v.end());
}

Q7: How to use custom comparisons?

A: Provide a custom comparison function.

struct Person {
    std::string name;
    int age;
};

std::vector<Person> people;

auto youngest = std::min_element(people.begin(), people.end(),
    [](const Person& a, const Person& b) {
        return a.age < b.age;
    });

Q8: Where can I learn more about MinMax?

A:

Related Posts: algorithm, sort, clamp.

Summary: The MinMax algorithm is an STL algorithm for finding the minimum and maximum values.


Here are some related posts to this topic:

Practical Tips

Here are some tips for applying this concept in real-world scenarios.

Debugging Tips

  • Check compiler warnings first if issues arise
  • Reproduce the issue with simple test cases

Performance Tips

  • Avoid optimizing without profiling
  • Set measurable performance goals first

Code Review Tips

  • Ensure the code’s intent is clear
  • Provide sufficient test cases
  • Follow your team’s coding conventions

Practical Checklist

Use this checklist to ensure proper application of this concept in real-world projects.

Before Writing Code

  • Is this the best approach to solve the current problem?
  • Can team members understand and maintain this code?
  • Does it meet performance requirements?

While Writing Code

  • Have all compiler warnings been resolved?
  • Have edge cases been considered?
  • Is error handling appropriate?

During Code Review

  • Is the intent of the code clear?
  • Are there sufficient test cases?
  • Is the documentation complete?

Use this checklist to reduce errors and improve code quality.


Keywords Covered in This Post (Related Search Terms)

Search for terms like C++, algorithm, min, max, STL to find more resources related to this post.