모두의 코드
C++ 레퍼런스 - remove 와 remove_if 함수 (<algorithm>)

작성일 : 2019-02-18 이 글은 23773 번 읽혔습니다.

아직 C++ 에 친숙하지 않다면 씹어먹는 C++ 은 어때요?

remove, remove_if

<algorithm> 에 정의됨

template <class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
                       const T& val);

template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p );

범위 내에 특정 값을 가진 원소들을 제거한다.

범위 (first 부터 last 전 까지) 내에 원소들 중에서 val 과 값이 일치하는 원소(remove)들 혹은 조건 p 를 만족하는 원소(remove_if)를 제거한 범위로 변환합니다. 이 때 이 함수는 해당 범위의 맨 끝을 가리키는 반복자를 리턴합니다.

참고로 이 함수는 실제로 원소를 제거하는 것이 아닙니다. 다만, 지워야 하는 원소들을 컨테이너 맨 뒤로 보내버릴 뿐입니다.

즉, 위 함수가 리턴하는 반복자 부터 last 까지 원소들이 바로 val 과 일치하는 원소들로 대체됩니다. 따라서, 실제로 조건을 만족하는 원소들을 지워 버리기 위해서는 추가적으로 컨테이너들의 erase 함수를 호출해야 합니다.

지워지진 않은 원소들의 상대적 위치는 유지됩니다. 하지만, 지워질 원소들의 상대적 위치의 경우 유지됨이 보장되지 않습니다.

이 함수는 operator== 를 이용해서 원소를 비교합니다.

인자들

  • first, last : 원소의 시작과 끝을 가리키는 반복자들. 이 때 확인하는 범위는 [first, last) 로 정의됩니다. 이들은 타입 T 와 비교 가능해야 하며 (operator== 로), 이동 가능해야만 합니다.

  • val : 삭제할 값

  • p : 원소를 한 개만 가지는 단항 함수로 p 의 리턴값은 bool 로 변환 가능해야만 합니다. 이 때, p 는 원소를 변경하면 안됩니다.

리턴값

지워지지 않은 마지막 원소 바로 뒤를 가리키는 반복자를 리턴한다. 즉 first 부터 이 함수가 리턴하는 반복자 바로 전 까지 val 과 일치하지 않는 원소들이 된다.

구현 예시

remove

template <class ForwardIt, class T>
ForwardIt remove(ForwardIt first, ForwardIt last, const T& value) {
  first = std::find(first, last, value);
  if (first != last)
    for (ForwardIt i = first; ++i != last;)
      if (!(*i == value)) *first++ = std::move(*i);
  return first;
}

remove_if

template <class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p) {
  first = std::find_if(first, last, p);
  if (first != last)
    for (ForwardIt i = first; ++i != last;)
      if (!p(*i)) *first++ = std::move(*i);
  return first;
}

실행 예제

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

int main() {
  std::string str1 = "Text with some   spaces";
  // 문자열에서 띄어쓰기를 모두 지운다.
  str1.erase(std::remove(str1.begin(), str1.end(), ' '), str1.end());
  std::cout << str1 << '\n';

  std::string str2 = "Text\n with\tsome \t  whitespaces\n\n";
  // 문자열에서 공백 문자 (띄어쓰기, 개행 문자 등등)를 지운다.
  str2.erase(std::remove_if(str2.begin(), str2.end(),
                            [](unsigned char x) { return std::isspace(x); }),
             str2.end());
  std::cout << str2 << '\n';
}

실행 결과

실행 결과

Textwithsomespaces
Textwithsomewhitespaces

참고 자료

  • remove_copy : 특정 값들을 복사한 후 지운다.

  • replace : 특정 범위의 원소들을 치환한다.

  • count : 특정 값과 일치하는 원소의 개수를 센다.

  • find : 범위 안에 원소들 중 값이 일치하는 원소를 찾는다.

첫 댓글을 달아주세요!
프로필 사진 없음
강좌에 관련 없이 궁금한 내용은 여기를 사용해주세요

    댓글을 불러오는 중입니다..