C++ STL : <algorithm> 헤더

김종민·2025년 3월 6일

C++

목록 보기
4/5

1. <algorithm>

C++ 표준 라이브러리 중 하나로 원소들의 범위를 가지고 수행하는 다양한 함수들이 정의되어있다.
ex) 검색, 정렬, 갯수 세기, 조작...

범위는 [first , last) 형태로 last는 작업할 원소의 바로 뒤이다.


2. 자주 사용되는 함수

함수 정리된 링크

count() : 갯수 세기

문법

template <class InputIterator, class T>  typename
iterator_traits<InputIterator>::difference_type    count (InputIterator first, InputIterator last, const T& val);

[first , last) 범위 내에서 val에 해당하는 값이 몇 개인지 반환한다.

예시

#include <iostream>     // std::cout
#include <algorithm>    // std::count
#include <vector>       // std::vector

int main () {
  // 배열에서 카운팅
  int myints[] = {10,20,30,30,20,10,10,20};   // 8개 원소
  int mycount = std::count (myints, myints+8, 10); // 주소로 지정
  std::cout << "10 appears " << mycount << " times.\n";

  // 벡터에서 카운팅
  std::vector<int> myvector (myints, myints+8);
  mycount = std::count (myvector.begin(), myvector.end(), 20); // 이터레이터로 범위 지정
  std::cout << "20 appears " << mycount  << " times.\n";

  return 0;
}

출력

10 appears 3 times.
20 appears 3 times.

count_if() : 갯수 세기 (조건 사용)

문법

template <class InputIterator, class UnaryPredicate>  typename 
iterator_traits<InputIterator>::difference_type    count_if (InputIterator first, InputIterator last, UnaryPredicate pred);

[first , last) 범위 내에서 pred 조건에 해당하는 값이 몇 개인지 반환한다.

UnaryPredicate pred

범위 내 원소를 인자로 받는 단항 함수(Unary function)이면서 부울형식으로 표현 가능한 값을 리턴해야한다.

단항 함수 : 인자를 하나만 받는 함수

예시 1 : 별개의 함수 사용

#include <iostream>     // std::cout
#include <algorithm>    // std::count_if
#include <vector>       // std::vector

bool IsOdd (int i) { return ((i%2)==1); } // 홀수라면 true (카운트)

int main () {
  std::vector<int> myvector;
  for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9

  int mycount = count_if (myvector.begin(), myvector.end(), IsOdd);
  std::cout << "myvector contains " << mycount  << " odd values.\n";

  return 0;
}

출력

myvector contains 5 odd values.

예시 2 : 람다 함수 사용

#include <iostream>     // std::cout
#include <algorithm>    // std::count_if
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector;
  for (int i=1; i<10; i++) myvector.push_back(i); // myvector: 1 2 3 4 5 6 7 8 9

  int mycount = count_if (myvector.begin(), myvector.end(), [](int i) { return ((i%2)==1); }); // 람다 함수
  std::cout << "myvector contains " << mycount  << " odd values.\n";

  return 0;
}

출력

myvector contains 5 odd values.

reverse() : 역순으로 정렬하기

문법

template <class BidirectionalIterator>  
void reverse (BidirectionalIterator first, BidirectionalIterator last);

[first , last) 범위의 원소를 역순으로 정렬한다.

예시

#include <iostream>     // std::cout
#include <algorithm>    // std::reverse
#include <vector>       // std::vector

int main () {
  std::vector<int> myvector;

  for (int i=1; i<10; ++i) myvector.push_back(i);   // 1 2 3 4 5 6 7 8 9
  
  // 역으로 정렬
  std::reverse(myvector.begin(),myvector.end());    // 9 8 7 6 5 4 3 2 1
  
  // 출력
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
  {
    std::cout << ' ' << *it;
  }

  return 0;
}

출력할 때 이터레이터를 사용했기때문에 *it로 값을 불러온다.

출력

9 8 7 6 5 4 3 2 1

sort() : 정렬하기

문법

// 기본
template <class RandomAccessIterator>  
void sort (RandomAccessIterator first, RandomAccessIterator last);

// 커스텀 정렬
template <class RandomAccessIterator, class Compare>  
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

[first , last) 범위의 원소를 오름차순으로 정렬한다.

comp 함수를 인자로 넣어 원하는 조건으로 정렬할 수 있다.

정렬 과정에서 원래의 원소 순서가 변할 수 있는 불안정 정렬이다.
순서가 보장되는 정렬 : stable_sort 사용하기

예시

#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector

// 커스텀 함수 , **내림차순으로 정렬되도록 했음 (i > j)**
bool myfunction (int i,int j) { return (i>j); }

// 함수 객체도 가능
struct myclass {
  bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
  int myints[] = {32,71,12,45,26,80,53,33};
  std::vector<int> myvector (myints, myints+8);               // 32 71 12 45 26 80 53 33

  // 기본 오름차순 정렬
  std::sort (myvector.begin(), myvector.begin()+4);           //(12 32 45 71)26 80 53 33

  // 커스텀 함수 사용 (내림차순)
  std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(80 53 33 26)

  // 함수 객체 사용
  std::sort (myvector.begin(), myvector.end(), myobject);     //(12 26 32 33 45 53 71 80)

  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
  {
    std::cout << ' ' << *it;
  }
  
  std::cout << '\n';

  return 0;
}

출력

myvector contains: 12 26 32 33 45 53 71 80

min_element() : 최솟값 구하기

문법

template <class ForwardIterator>  
ForwardIterator min_element (ForwardIterator first, ForwardIterator last);

// 커스텀 정렬
template <class ForwardIterator, class Compare>  
ForwardIterator min_element (ForwardIterator first, ForwardIterator last,Compare comp);

[first , last) 범위 내에서 가장 작은 원소값의 이터레이터를 리턴한다.
범위가 비어있다면 last를 리턴한다.

comp 함수를 인자로 넣어 원하는 조건으로 정렬할 수 있다.

최댓값은 max_element() 사용하면 된다.

예시

// min_element/max_element example
#include <iostream>     // std::cout
#include <algorithm>    // std::min_element, std::max_element

// 커스텀 함수
bool myfn(int i, int j) { return i<j; }

// 함수 객체
struct myclass {
  bool operator() (int i,int j) { return i<j; }
} myobj;

int main () {
  int myints[] = {3,7,2,5,6,4,9};

  // 기본 정렬 방식
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7) << '\n';

  // 커스텀 함수 사용
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myfn) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myfn) << '\n';

  // 함수 객체 사용
  std::cout << "The smallest element is " << *std::min_element(myints,myints+7,myobj) << '\n';
  std::cout << "The largest element is "  << *std::max_element(myints,myints+7,myobj) << '\n';

  return 0;
}

출력

The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9
The smallest element is 2
The largest element is 9

참고 자료

https://cplusplus.com/reference/algorithm/
https://cplusplus.com/reference/algorithm/count_if/

profile
정리와 기록

0개의 댓글