카테고리 없음

C++ STL -알고리즘 (sort, find), 반복자

dkuen 2026. 3. 12. 17:07

STL은 다양한 컨테이너와 독립적으로 동작하는 범용 알고리즘을 제공합니다.

예를 들어, 특정 원소 값을 찾거나, 정렬을 하는 등의 기능을 표준 라이브러리에서 바로 사용할 수 있습니다.

 

sort

컨테이너 내부의 데이터를 정렬하는 함수입니다.

기본 타입의 경우 사용자 정렬 함수 없으면 오름차순으로 정렬됩니다.

또한 사용자 정렬 함수를 정의할 수도 있습니다.

 

사용자 정렬 함수 comp(a, b) 구현 시 알아두어야 할 것은 아래와 같습니다.

  1. 현재 컨테이너에서 첫 번째 인자 a가 앞에 있는 원소를 의미합니다.
  2. comp(a, b)가 true 이면 a와 b의 순선느 유지됩니다.
    만약 false인 경우 a와 b의 순서를 바꿉니다.
//sort를 활용, 기본타입 배열을 정렬하는 예시(정렬 기준 없음)

#include <iostream>
#include <algorithm> // sort 함수 포함
using namespace std;

int main() {
    int arr[] = {5, 2, 9, 1, 5, 6};
    int size = sizeof(arr) / sizeof(arr[0]);

    // 오름차순 정렬
    sort(arr, arr + size);

    // 결과 출력
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}

 

//sort를 활용, 기본타입 배열을 정렬하는 예시(정렬 기준 있음)

#include <iostream>
#include <algorithm> // sort 함수 포함
using namespace std;

bool compare(int a, int b) {
    return a > b; // 내림차순
}

int main() {
    int arr[] = {5, 2, 9, 1, 5, 6};
    int size = sizeof(arr) / sizeof(arr[0]);

    // 내림차순 정렬
    sort(arr, arr + size, compare);

    // 결과 출력
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
    return 0;
}

//sort를 활용, 기본타입 벡터를 정렬하는 예시(정렬 기준 없음)

#include <iostream>
#include <vector>
#include <algorithm> // sort 함수 포함
using namespace std;

int main() {
    vector<int> vec = {5, 2, 9, 1, 5, 6};

    // 오름차순 정렬
    sort(vec.begin(), vec.end());

    // 결과 출력
    for (int num : vec) {
        cout << num << " ";
    }
    return 0;
}
//sort를 활용, 기본타입 벡터를 정렬하는 예시(정렬 기준 있음)

#include <iostream>
#include <vector>
#include <algorithm> // sort 함수 포함
using namespace std;

bool compare(int a, int b) {
    return a > b; // 내림차순
}

int main() {
    vector<int> vec = {5, 2, 9, 1, 5, 6};

    // 내림차순 정렬
    sort(vec.begin(), vec.end(), compare);

    // 결과 출력
    for (int num : vec) {
        cout << num << " ";
    }
    return 0;
}
//sort를 활용, class타입 벡터를 정렬하는 예시

#include <iostream>
#include <vector>
#include <algorithm> // sort 함수 포함
using namespace std;

class Person {
private:
    string name;
    int age;

public:
    // 생성자
    Person(string name, int age) : name(name), age(age) {}

    // Getter 함수
    string getName() const { return name; }
    int getAge() const { return age; }
};

// 다중 기준 정렬 함수 (나이 오름차순 → 이름 오름차순)
bool compareByAgeAndName(const Person& a, const Person& b) {
    if (a.getAge() == b.getAge()) {
        return a.getName() < b.getName(); // 이름 오름차순
    }
    return a.getAge() < b.getAge(); // 나이 오름차순
}

int main() {
    vector<Person> people = {
        Person("Alice", 30),
        Person("Bob", 25),
        Person("Charlie", 35),
        Person("Alice", 25)
    };

    // 나이 → 이름 순으로 정렬
    sort(people.begin(), people.end(), compareByAgeAndName);

    // 결과 출력
    for (const Person& person : people) {
        cout << person.getName() << " (" << person.getAge() << ")" << endl;
    }
    return 0;
}

사용자가 정의한 클래스 같은 경우에는 정렬 함수가 필수적으로 구현되어야 합니다.

 

find

find는 컨테이너 내부에서 특정 원소를 찾아 해당 원소의 반복자를 반환하는 함수입니다.

세부 동작은 아래와 같습니다.

find( first last, 찾을 값 )과 같이 사용하며, 세부 사항은 아래와 같습니다.

  1. find(first, last)가 탐색 대상입니다.
  2. 원소를 찾은 경우 해당 원소의 반복자를 반환합니다.
  3. 원소를 찾지 못한 경우 last 반복자를 반환합니다.
//벡터에서 특정 값 찾기

#include <iostream>
#include <vector>
#include <algorithm> // find 함수 포함
using namespace std;

int main() {
    vector<int> vec = {10, 20, 30, 40, 50};

    // 특정 값 30을 찾음
    auto it = find(vec.begin(), vec.end(), 30);

    if (it != vec.end()) {
        cout << "값 30이 벡터에서 발견됨, 위치: " << (it - vec.begin()) << endl;
    } else {
        cout << "값 30이 벡터에 없음" << endl;
    }
    return 0;
}

//배열에서 특정 값 찾기

#include <iostream>
#include <algorithm> // find 함수 포함
using namespace std;

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);

    // 특정 값 4를 찾음
    auto it = find(arr, arr + size, 4);

    if (it != arr + size) {
        cout << "값 4가 배열에서 발견됨, 위치: " << (it - arr) << endl;
    } else {
        cout << "값 4가 배열에 없음" << endl;
    }
    return 0;
}

 

여기서 끝 주소는 첫 번째 주소에서 size만큼 더한 값인데, 그럼 배열의 주소 범위를 넘어가게 됩니다.

하지만 find는 끝 주소에서 바로 직전 주소 까지만 탐색합니다.

못 찾았을 때는 arr + size를 반환합니다.

//문자열에서 특정 문자 찾기

#include <iostream>
#include <algorithm> // find 함수 포함
#include <string>
using namespace std;

int main() {
    string str = "hello world";

    // 문자 'o' 찾기
    auto it = find(str.begin(), str.end(), 'o');

    if (it != str.end()) {
        cout << "문자 'o'가 문자열에서 발견됨, 위치: " << (it - str.begin()) << endl;
    } else {
        cout << "문자 'o'가 문자열에 없음" << endl;
    }
    return 0;
}

 

반복자

컨테이너 구현 방식에 의존하지 않고(내부 구현을 몰라도) 알고리즘을 활용하는데 문제가 없습니다.

이는 반복자를 기반으로 알고리즘이 동작하기 때문입니다.

반복자는 컨테이너 요소에 대한 일관된 접근 방법을 제공, 알고리즘이 특정 컨테이너의 내부 구현과 무관하게 동작할 수 있습니다.

순방향 반복자

순방향 반복자는 앞에서부터 뒤로 순차적으로 순회하는 반복자입니다.

  1. begin()은 컨테이너의 첫 번째 원소를 가리키는 반복자입니다.
  2. end()는 컨테이너의 마지막 원소 다음을 가리키는 반복자입니다.

end()를 마지막 원소 다음을 가리키도록 정한 이유는 아래와 같습니다.

  1. 일관된 반복 구조를 유지합니다.
  2. 탐색 실패를 쉽게 표현할 수 있습니다. (마지막 원소 다음은 아무것도 없기 때문)
//벡터에서 순방향 반복자를 사용하는 예시

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

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // 순방향 반복자를 사용해 짝수만 출력
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        if (*it % 2 == 0) {
            cout << *it << " ";
        }
    }
    return 0;
}
// 출력: 2 4 6 8 10
//맵에서 순방향 반복자를 사용하는 예시

#include <map>
#include <iostream>
using namespace std;

int main() {
    map<string, int> scores = {{"Alice", 90}, {"Bob", 85}, {"Charlie", 88}};
    
    // 순방향 반복자를 사용해 맵의 키-값 쌍 출력
    for (auto it = scores.begin(); it != scores.end(); ++it) {
        cout << it->first << ": " << it->second << endl;
    }
    return 0;
}
// 출력:
// Alice: 90
// Bob: 85
// Charlie: 88
//문자열에서 순방향 반복자를 사용하는 예시

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

int main() {
    vector<string> words = {"apple", "banana", "cherry", "date"};

    string target = "cherry";

    auto it = find(words.begin(), words.end(), target);

    if (it != words.end()) {
        cout << "Word \"" << target << "\" found at index " << distance(words.begin(), it) << endl;
    } else {
        cout << "Word \"" << target << "\" not found." << endl;
    }

    return 0;
}
// 출력: Word "cherry" found at index 2

 

역방향 반복자

역방향 반복자는 컨테이너의 마지막 원소부터 첫 번째 원소까지 역순으로 순회할 수 있도록 해주는 반복자입니다.

  1. rbegin( )은 컨테이너의 마지막 원소를 가리키는 역방향 반복자입니다.
  2. rend( )는 컨테이너의 첫 번째 원소 이전을 가리키는 역방향 반복자입니다.

예를 들어, 컨테이너의 첫 번째 원소까지 탐색했지만 원하는 원소를 찾지 못한 경우, rend( )를 반환하여 탐색 실패를 명확하게 표현할 수 있습니다.

//벡터에서 역방향 반복자를 사용한 예시

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

int main() {
    vector<int> numbers = {10, 15, 20, 25, 30};

    // 역방향 반복자로 짝수만 출력
    for (auto it = numbers.rbegin(); it != numbers.rend(); ++it) {
        if (*it % 2 == 0) {
            cout << *it << " ";
        }
    }

    return 0;
}
// 출력: 30 20 10
//맵에서 역방향 반복자를 사용한 예시

#include <map>
#include <iostream>
using namespace std;

int main() {
    map<string, int> scores = {{"Alice", 90}, {"Bob", 85}, {"Charlie", 88}};

    // 역방향 반복자로 값이 88 이상인 항목만 출력
    for (auto it = scores.rbegin(); it != scores.rend(); ++it) {
        if (it->second >= 88) {
            cout << it->first << ": " << it->second << endl;
        }
    }

    return 0;
}
// 출력:
// Charlie: 88
// Alice: 90
//문자열에서 역방향 반복자를 사용한 예시

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

int main() {
    vector<string> words = {"apple", "banana", "cherry", "date"};

    string target = "banana";

    auto it = find(words.rbegin(), words.rend(), target);

    if (it != words.rend()) {
        cout << "Word \"" << target << "\" found at reverse index " 
             << distance(words.rbegin(), it) << " (from the back)" << endl;
        cout << "Word \"" << target << "\" found at forward index " 
             << distance(words.begin(), it.base()) - 1 << " (from the front)" << endl;
    } else {
        cout << "Word \"" << target << "\" not found." << endl;
    }

    return 0;
}
// 출력:
// Word "banana" found at reverse index 2 (from the back)
// Word "banana" found at forward index 1 (from the front)

 

distance(시작 iterator, 끝 iterator)

시작 iterator에서 끝 iterator까지의 거리를 의미합니다.