Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 정렬된 pair 벡터에서 이진 탐색 구현하기

이 글에서는 C++를 사용하여 정렬된 pair 벡터에서 이진 탐색(Binary Search)을 구현하는 방법을 단계별로 살펴봅니다.

핵심 개념

이진 탐색은 정렬된 자료구조에서 원하는 값을 O(log n)의 시간 복잡도로 빠르게 찾는 알고리즘입니다. C++ 표준 라이브러리(STL)는 <algorithm> 헤더의 binary_search() 함수를 제공하며, 이 함수는 탐색 범위와 찾으려는 값, 그리고 선택적으로 비교 기준을 인자로 받습니다.

pair<int, int>처럼 두 개의 값을 담는 요소를 다룰 때는 일반적으로 first(첫 번째 값)를 기준으로 탐색합니다. 하지만 binary_search()는 기본적으로 요소 전체를 비교하기 때문에, first 값만으로 비교하려면 사용자 정의 비교 함수(함수 객체)를 직접 작성해야 합니다.

알고리즘

시작
    keycompare 구조체를 선언한다.
        함수 operator()(const pair& v, const int& k)
        → bool 반환
            status = v.first < k
            status 반환
        함수 operator()(const int& k, const pair& v)
        → bool 반환
            status = k < v.first
            status 반환
    벡터 v를 선언한다.
    정수형 key-value 쌍을 v에 저장한다.
    push_back() 함수를 호출하여 v 벡터에 값을 삽입한다.
    sort() 함수를 호출하여 v 벡터의 모든 요소를 정렬한다.
    "정렬된 벡터"를 출력한다.
    "KEY"와 "VALUE"를 출력한다.
    for (pair& n : v)
        n의 first 값과 second 값을 출력한다.
    만약 binary_search(v.begin(), v.end(), 50, keycompare())의 결과가 참이면
        "50 exists in vector"를 출력한다.
    아니면
        "50 does not exist"를 출력한다.
    만약 binary_search(v.begin(), v.end(), 7, keycompare())의 결과가 참이면
        "7 exists in vector"를 출력한다.
    아니면
        "7 does not exist"를 출력한다.
종료

예제 코드

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

// first 값을 기준으로 pair와 int를 비교하는 함수 객체
struct keycompare {
    // (pair, int) 순서 비교
    bool operator()(const pair<int, int>& v, const int& k) {
        return (v.first < k);
    }
    // (int, pair) 순서 비교
    bool operator()(const int& k, const pair<int, int>& v) {
        return (k < v.first);
    }
};

int main() {
    vector<pair<int, int>> v;
    v.push_back(make_pair(7, 26));
    v.push_back(make_pair(6, 76));
    v.push_back(make_pair(4, 16));
    v.push_back(make_pair(5, 36));

    // first 값을 기준으로 벡터 정렬
    sort(v.begin(), v.end());

    cout << "Sorted vector" << endl;
    cout << "KEY" << '\t' << "VALUE" << endl;
    for (pair& n : v)
        cout << n.first << '\t' << n.second << endl;

    // 50 검색
    if (binary_search(v.begin(), v.end(), 50, keycompare()))
        cout << "50 exists in vector";
    else
        cout << "50 does not exist";
    cout << endl;

    // 7 검색
    if (binary_search(v.begin(), v.end(), 7, keycompare()))
        cout << "7 exists in vector";
    else
        cout << "7 does not exist";

    return 0;
}

실행 결과

Sorted vector
KEY     VALUE
4       16
5       36
6       76
7       26
50 does not exist
7 exists in vector

코드 설명

1. keycompare 구조체

keycompareoperator()를 두 가지 방식으로 오버로드한 함수 객체입니다. 하나는 (pair, int) 순서의 비교를, 다른 하나는 (int, pair) 순서의 비교를 담당합니다.

binary_search() 내부에서는 "찾으려는 값 < 범위의 요소"와 "범위의 요소 < 찾으려는 값" 두 방향의 비교가 모두 수행됩니다. 따라서 두 오버로드가 반드시 함께 정의되어야 컴파일 오류 없이 동작합니다.

2. 정렬과 탐색

sort()는 pair의 first 값을 우선 기준으로 오름차순 정렬합니다. 정렬이 완료된 후 binary_search()keycompare()를 전달하면 first 값만을 기준으로 탐색이 진행됩니다.

3. 실행 결과 분석

벡터에는 4, 5, 6, 7이라는 키가 저장되어 있으므로, 50은 존재하지 않아("does not exist") 거짓이 출력되고, 7은 존재하므로("exists") 참이 출력됩니다.

💡 이진 탐색의 시간 복잡도는 O(log n)으로 매우 효율적이지만, 반드시 데이터가 사전에 정렬되어 있어야 올바른 결과를 보장합니다.