[Modern C++] 10.3. STL(3)

윤정민·2023년 7월 10일
0

C++

목록 보기
28/46

1. Algorithm Library

프로그래밍에 도움이 되는 여러 작업을 쉽게할 수 있도록 도와주는 라이브러리로 주로 정렬알고리즘이나 컨테이너 관련 작업들이 있다.

1.1. 함수들의 형태

  • 조건이 없는 경우
template <typename Iter>
void do_something(Iter begin, Iter end);
  • 조건이 있는 경우
template <typename Iter, typename Pred>
void do_something(Iter begin, Iter end, Pred pred)

1. 정렬

  • sort: 일반적인 정렬 O(nlogn)
  • stable_sort: 정렬을 하되 원소들 간의 순서를 보존 O(n(logn)^2)
  • partial_sort: 배열의 일부분만 정렬

1.1. 주의할 점

  • sort에 들어가는 반복자의 경우 반드시 임의접근 반복자 타입을 만족해야 함(list넣으면 오류남)

2. 삭제

  • remove: erase를 사용해 하나씩 삭제하기 힘들었던 작업을 편하게 수행 가능
  • remove_if: 세번째 인자로 조건을 설명할 함수 객체를 전달 받음
    • 해당 함수는 이전의 호출에 의해 내부 상태가 달라지면 안됨

3. 람다함수

이름이 없는 함수
[capture list](받는 인자)->리턴 타입{함수 본체}

  • 예시
    • 인자로 int i를 받고, bool을 리턴하는 람다 함수
      [](int i) -> bool { return i % 2 == 1; }
    • 리턴타입을 생략해 사용가능(유추가능할 때만)
      [](int i) { return i % 2 == 1; }
    • 생성후 호출 방법
    auto func = [](int i) { return i % 2 == 1; };
    func(4);  // false;
  • 람다함수도 자신만의 스코프를 가지기 때문에 외부에서 정의된 변수를 사용할 수 없음
    • 캡쳐 목록을 사용하면 접근 가능
     vec.erase(std::remove_if(vec.begin(), vec.end(),
                        [&num_erased](int i) {  //캡쳐목록으로 num_erased사용
                          if (num_erased >= 2)
                            return false;
                          else if (i % 2 == 1) {
                            num_erased++;
                            return true;
                          }
                          return false;
                        }),
              vec.end());
    • 클래스 내 멤버 변수에 접근하는 법
      • this를 전달
      vec.erase(std::remove_if(vec.begin(), vec.end(),
                           [this](int i) {
                             if (this->num_erased >= 2)
                               return false;
                             else if (i % 2 == 1) {
                               this->num_erased++;
                               return true;
                             }
                             return false;
                           }),
            vec.end());

4. 원소 수정하기

remove와 마찬가지로 한번에 원하는 원소들의 값을 변경할 수 있다.

transform (시작 반복자, 끝 반복자, 결과를 저장할 컨테이너의 시작 반복자, Pred)

  • 결과를 저장할 컨테이너는 원래 크기의 컨테이너보다 최소한 같거나 커야함

  • 예시

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

template <typename Iter>
void print(Iter begin, Iter end) {
  while (begin != end) {
    std::cout << "[" << *begin << "] ";
    begin++;
  }
  std::cout << std::endl;
}

int main() {
  std::vector<int> vec;
  vec.push_back(5);
  vec.push_back(3);
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(3);
  vec.push_back(4);

  std::cout << "처음 vec 상태 ------" << std::endl;
  print(vec.begin(), vec.end());

  std::cout << "벡터 전체에 1 을 더한다" << std::endl;
  std::transform(vec.begin(), vec.end(), vec.begin(),
                 [](int i) { return i + 1; });
  print(vec.begin(), vec.end());
}

5. 원소를 탐색하는 함수

  • find: firtst부터 last까지 순회하며 value와 같은 원소가 있는지 확인 후 이를 가리키는 반복자를 리턴
profile
그냥 하자

0개의 댓글