C++

[C++]STL(Standard Template Library)

programmer-faust 2025. 6. 11. 19:47
    • 순서
      1. STL이란?
      2. 컨테이너
      3. 벡터
      4. 알고리즘
      5. 반복자
    • STL이란?
      1. C++ 표준 라이브러리의 핵심 구성 요소 중 하나로 자료구조, 알고리즘, 반복자를 제네릭하게 제공하는 라이브러리임.
      2. 제네릭 프로그래밍 철학을 기반으로 설계하여 템플릿을 사용해서 자료형에 상관없이 동작함
      3. 최적화된 자료구조와 알고리즘을 제공하며, 코드 재사용성, 안정성, 성능을 확보함
    • 컨테이너
      1. 데이터를 담는 자료구조를 뜻함. (데이터를 담는 방식이나 제공하는 메서드에 따라 여러 가지 컨테이너를 제공함)
      2. 모든 컨테이너는 템플릿으로 구현되어 있으며, 다양한 타입의 데이터를 저장할 수 있음
      3. 모든 컨테이너는 메모리 관리를 내부적으로 하기 때문에 사용시 메모리 해제를 직접 고려하지 않아도 됨.
      4. 대부분의 컨테이너는 반복자를 제공하기 때문에 내부 구현을 몰라도 동일한 방식으로 컨테이너를 순회할 수 있음.
      5. 시퀀스 컨테이너, 연관 컨테이너, 비정렬 컨테이너, 컨테이너 어댑터가 있음.
        • 시퀀스 컨테이너: vector, deque, list, forward_list, array
        • 연관 컨테이너: set, multiset, map, multimap
        • 비정렬 연관 컨테이너: unordered_set, unordered_multiset, unordered_map, unordered_multimap
        • 컨테이너 어댑터: stack, queue, priority_queue
    • 벡터
      1. 벡터의 특징 : 배열과 매우 유사한 컨테이너이다.
        • 템플릿 클래스로 구현되어 특정 타입에 종속되지 않는다.
        • 삽입되는 원소 개수에 따라 배열의 크기가 자동으로 조정됨
        • 임의적으로 접근이 가능함.(인덱스를 통해 특정 위치에 접근)
        • 삽입/삭제는 맨 뒤에 하는 것이 좋음(중간 삽입/삭제는 배열 복사가 필요하기 때문에 비효율 적임.)
      2. 벡터의 선언 : 선언의 방식은 타입만 명시하거나 초기값까지 같은 선언하는 경우가 있음
        • 빈 벡터를 선언하거나 특정 값으로 초기화하는 방법.
        •  초기화 리스트를 사용하여 벡터를 선언하는 방법.
          • <특정 값으로 벡터를 초기화할 때 자주 사용, 초기화하는 원소의 개수가 적을 때 주로 활용함>
        • 다른 벡터를 복사하거나 대입하는 방법.
          • <기존에 생성된 벡터의 복사본을 만들 때 많이 사용함>
        • 2차원 배열처럼 벡터를 사용하는 방법.
          • <벡터의 타입을 벡터로 선언하여 2차원 벡터처럼 사용하는 방법.>
      3. 벡터의 동작
        • push_back
          • 벡터의 맨 끝에 원소를 추가하는 메서드이다. 원소의 개수가 늘어남에 따라 크기는 자동으로 증가하여 별도의 메모리 관리를 신경 쓸 필요가 없다.
        • pop_back
          • 벡터의 맨 끝에 원소를 제거하는 메서드이다. 맨 끝 원소가 제거되면 벡터 크기가 자동으로 줄어들게 된다.
        • size
          • 벡터의 크기(원소 개수)를 확인할 때 사용하는 메서드이다. 보통 벡터의 전체 원소를 대상으로 반복문을 돌리 때 유용하게 쓰임
        • erase
          • 특정 위치(또는 구간)의 원소를 제거하는 함수이다. 벡터는 내부적으로 배열을 사용하므로, 중간 원소를 삭제할 때, 많은 원소를 옮겨야 할 수 있음. => 시간 복잡도가 커질 수 있으므로, 자주 사용하지 않는 것이 좋음
      1. 맵은 키를 활용하여 값과 함께 쌍으로 저장하고, 특정 키를 사용하여 값을 검색하는 기능을 제공하는 연관 컨테이너이다.
      2. 맵의 특징
        • 키-값 쌍은 pair<const Key, Value>형태로 저장됨
        • 키값을 기준으로 내부 데이터가 자동으로 정렬됨
        • 중복된 키값을 허용하지 않음
      3. 맵의 선언
        • 맵을 선언할 때 키-값 쌍을 저장하기 위해 키 타입과 값 타입 두가지를 지정해야함. 이 두 타입은 동일할 수도 있고, 서로 다를 수도 있으며, 키 타입은 비교 연산이 가능해야함.

<좌>키와 값이 다를 경우 / <우>키와 값이 같은 경우

    1.  
    2. 맵의 동작
      • map은 key 순으로 오름차순 정렬됨
        • 사용자가 따로 정렬을 수행하지 않아도, 삽입 및 삭제가 이루어질 때마다 내부적으로 정렬상태를 유지하기 때문
      • insert()
        • make_pair()를 이용하여 pair 객체를 생성한 후 insert 함수를 사용할 수 있음.
        • {}(스코프)를 활용한 방법이나 [](인덱스)를 사용하여 값을 추가할 수 있음.
      • find()
        • find 메서드를 사용하면 특정 키가 map에 존재하는지 확인할 수 있음
        • find는 키가 존재하면 해당 키의 이터레이터를 반환하고, 존재하지 않으면 map.end()를 반환함.
      • size()
        • 맵에 키-값 쌍의 개수를 반환하는 함수
      • erase(key)
        • 맵의 특정 key를 가진 요소만 삭제함
      • clear()
        • 맵에 있는 모든 원소를 삭제하는 함수.
        • clear는 맵뿐 아니라 대부분 컨테이너에 존재함
  • 알고리즘
    1. sort
        • 컨테이너 내부의 데이터를 정렬하는 함수
        • 기본타입(int, double 등)의 경우 사용자 정렬 함수 없으면 오름차순으로 정렬됨 또한 사용자 정렬 함수를 정의할 수도 있음
        • 사용자 정렬 함수comp(a, b)구현 시 true이면 a와 b의 순서는 유지됨 하지만 false인 경우 a와 b의 순서를 바꿈
      #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); //arr부터 arr+size까지 compare의 규칙에 따라서 정렬함
      
          // 결과 출력
          for (int i = 0; i < size; i++) {
              cout << arr[i] << " ";
          }
          return 0;
      }
    2. find
      • 컨테이너 내부에서 특정 원소를 찾아 해당 원소의 반복자를 반환하는 함수이다.
      • find(first last, 찾을 값)과 같이 사용함
          • find(first, last)가 탐색 대상
          • 원소를 찾은 경우 해당 원소의 반복자를 반환
          • 원소를 찾지 못한경우 last 반복자를 반환함
        #include <iostream>
        #include <vector> //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); //vec의 begin(맨앞)부터 end(끝까지) 탐색하여 30을 찾을것이다.
        
            if (it != vec.end()) {
                cout << "값 30이 벡터에서 발견됨, 위치: " << (it - vec.begin()) << endl;
            } else {
                cout << "값 30이 벡터에 없음" << endl;
            }
            return 0;
        }
  • 반복자
    1. 알고리즘의 사용
      • 알고리즘은 반복자를 기반으로 작동하기 때문에, 컨테이너의 내부 구현방식을 몰라도 알고리즘을 활용하는 것에 문제가 없음
      • 반복자는 컨테이너의 요소에 대한 일관된 접근 방식을 제공, 때문에 알고리즘이 특정 컨테이너의 내부 구현과 무관하게 동작할 수 있음
    2. 순방향 반복자
      • 앞에서부터 뒤로 순차적으로 순회하는 반복자
      • begin()은 컨테이너의 첫 번째 원소를 가리키는 반복자이다.
      • end()는 컨테이너의 마지막 원소 다음을 가리키는 반복자이다.
        • 일관된 반복 구조를 유지하고 탐색 실패를 쉽게 표현할 수 있기 때문에, end()를 마지막 원소 다음을 가리키도록 정함
    3. 역방향 반복자
      • 컨테이너의 마지막 원소부터 첫 번째 원소가지 역순으로 순회할 수 있도록 해주는 반복자
      • rbegin()은 컨테이너의 마지막 원소를 가리키는 역방향 반복자이다.
      • rend()는 컨테이너의 첫 번째 원소 이전을 가리키는 역방향 반복자이다.
        • 컨테이너의 첫 번째 원소까지 탐색했지만 원하는 원소를 찾지 못한 경우, rend()를 반환하여 탐색 실패를 명확하게 표현할 수 있음.

'C++' 카테고리의 다른 글

[C++]FMath  (0) 2025.06.18
[C++]객체지향적 설계  (0) 2025.06.11
[C++]템플릿  (0) 2025.06.09
[C++] 자원 관리하기  (0) 2025.06.09
[C++]프로그래밍 기초3  (0) 2025.06.02