💡 퀵 접속: cpp.kr/find_end

find_end

C++ 표준 라이브러리의 알고리즘으로, 첫 번째 범위에서 두 번째 범위와 일치하는 마지막 부분 범위를 찾습니다. 기본적으로 == 연산자를 사용하여 비교하며, 커스텀 비교 함수를 제공할 수 있습니다.

기본 사용법

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

int main() {
    std::vector<int> haystack = {1, 2, 3, 4, 5, 3, 4, 5, 6, 7};
    std::vector<int> needle = {3, 4, 5};
    
    // needle과 일치하는 마지막 부분 범위 찾기
    auto it = std::find_end(haystack.begin(), haystack.end(),
                           needle.begin(), needle.end());
    
    if (it != haystack.end()) {
        std::cout << "needle과 일치하는 마지막 부분 범위를 찾았습니다. 위치: " 
                  << std::distance(haystack.begin(), it) << std::endl;
        
        // 찾은 부분 범위 출력
        std::cout << "찾은 부분 범위: ";
        for (auto i = it; i != it + needle.size(); ++i) {
            std::cout << *i << " ";
        }
        std::cout << std::endl;
    } else {
        std::cout << "needle과 일치하는 부분 범위를 찾지 못했습니다." << std::endl;
    }
    
    return 0;
}

실행 결과:

needle과 일치하는 마지막 부분 범위를 찾았습니다. 위치: 5
찾은 부분 범위: 3 4 5

커스텀 비교 함수 사용

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

int main() {
    std::vector<double> haystack = {1.0, 2.0, 3.0, 4.0, 2.1, 3.1, 4.1, 5.0};
    std::vector<double> needle = {2.0, 3.0, 4.0};
    
    // 두 실수가 거의 같은지 비교하는 함수
    auto almost_equal = [](double a, double b) {
        return std::abs(a - b) < 0.2;
    };
    
    auto it = std::find_end(haystack.begin(), haystack.end(),
                           needle.begin(), needle.end(),
                           almost_equal);
    
    if (it != haystack.end()) {
        std::cout << "거의 일치하는 마지막 부분 범위를 찾았습니다. 위치: " 
                  << std::distance(haystack.begin(), it) << std::endl;
        
        // 찾은 부분 범위 출력
        std::cout << "찾은 부분 범위: ";
        for (auto i = it; i != it + needle.size(); ++i) {
            std::cout << *i << " ";
        }
        std::cout << std::endl;
    } else {
        std::cout << "거의 일치하는 부분 범위를 찾지 못했습니다." << std::endl;
    }
    
    return 0;
}

실행 결과:

거의 일치하는 마지막 부분 범위를 찾았습니다. 위치: 4
찾은 부분 범위: 2.1 3.1 4.1

사용자 정의 타입에서 사용

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

struct Person {
    std::string name;
    int age;
    
    bool operator==(const Person& other) const {
        return name == other.name && age == other.age;
    }
};

int main() {
    std::vector<Person> people = {
        {"Alice", 20},
        {"Bob", 25},
        {"Charlie", 30},
        {"Bob", 25},
        {"Charlie", 30},
        {"David", 35}
    };
    
    std::vector<Person> pattern = {
        {"Bob", 25},
        {"Charlie", 30}
    };
    
    // pattern과 일치하는 마지막 부분 범위 찾기
    auto it = std::find_end(people.begin(), people.end(),
                           pattern.begin(), pattern.end());
    
    if (it != people.end()) {
        std::cout << "pattern과 일치하는 마지막 부분 범위를 찾았습니다. 위치: " 
                  << std::distance(people.begin(), it) << std::endl;
        
        // 찾은 부분 범위 출력
        std::cout << "찾은 부분 범위:" << std::endl;
        for (auto i = it; i != it + pattern.size(); ++i) {
            std::cout << i->name << " (" << i->age << "세)" << std::endl;
        }
    } else {
        std::cout << "pattern과 일치하는 부분 범위를 찾지 못했습니다." << std::endl;
    }
    
    return 0;
}

실행 결과:

pattern과 일치하는 마지막 부분 범위를 찾았습니다. 위치: 3
찾은 부분 범위:
Bob (25세)
Charlie (30세)

참고사항

  • find_end는 algorithm 헤더에 정의되어 있습니다.
  • 기본적으로 == 연산자를 사용하여 비교합니다.
  • 커스텀 비교 함수를 제공할 수 있습니다.
  • 시간 복잡도는 O(n*m)입니다 (n은 첫 번째 범위의 크기, m은 두 번째 범위의 크기).
  • 두 번째 범위가 비어있으면 첫 번째 범위의 끝 반복자를 반환합니다.
  • 두 번째 범위를 찾지 못하면 첫 번째 범위의 끝 반복자를 반환합니다.
  • 부분 문자열 검색이나 패턴 매칭에 유용합니다.
  • search와 유사하지만, 마지막으로 일치하는 부분 범위를 찾습니다.
함수 설명
find_end(first1, last1, first2, last2) 기본 비교 연산자를 사용하여 두 번째 범위와 일치하는 마지막 부분 범위를 찾음
find_end(first1, last1, first2, last2, binary_pred) 커스텀 비교 함수를 사용하여 두 번째 범위와 일치하는 마지막 부분 범위를 찾음