본문 바로가기
C,C++/C++

[C++ STL] <algorithm> std::remove_if 함수

by woohyeon 2019. 11. 8.
반응형

안녕하세요.
오늘은 <algorithm> 헤더의 std::remove_if() 함수에 대해 알아보겠습니다.


template <class ForwardIterator, class UnaryPredicate>
  ForwardIterator remove_if (ForwardIterator first, ForwardIterator last, UnaryPredicate pred);

remove_if 함수는 Input 컨테이너의 [first, last) 범위의 요소들 중 서술 함수인 pred를 만족하지 않는 요소를 
Input 컨테이너의 처음부터 차례로 덮어씌웁니다(복사).

first, last 
Input 컨테이너의 범위로 주어진 반복자입니다.  [first1, last1) 범위의 컨테이너에서 요소를 탐색합니다. 


pred 
단항 연산을 하는 서술 함수로서 Input 컨테이너의 요소들 중 해당 함수를 만족하지 않을 때 복사합니다.
해당 함수는 bool 타입을 반환해야합니다.

반환 값
pred 함수가 마지막으로 적용된 요소의 다음을 가리키는 반복자를 반환합니다.
( = 제거하지 않은 마지막 요소 이후를 참조하는 반복자를 반환)



remove_if 함수는 아래와 같이 동작합니다.

remove_if 함수 동작 방식

먼저 만족하는 요소를 저장할 위치인 result 반복자를 first로 초기화합니다.
현재 반복자가 가리키는 요소가 pred 함수를 만족하지 않는다면 result 위치의 요소에 first 위치의 요소를 덮어 씌웁니다.
저장 후 result 반복자와 first 반복자가 다음 요소를 가리키도록 합니다. 

(std::move()는 인자를 임시객체로 만들어 rvalue reference를 반환시키고 소멸 상태에 가까운 null 객체로 만듭니다.
 rvalue reference 참고)
https://docs.microsoft.com/ko-kr/cpp/cpp/rvalue-reference-declarator-amp-amp?view=vs-2019


만약 pred 함수를 만족한다면 first 반복자만 1 증가시킨 후 다음 요소에 대해 이전 과정을 반복합니다.



예제)

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

using std::string;
using std::vector;
using std::cout;

bool isEven(int num)
{
	return num % 2 == 0;
}

int main(void)
{
	vector<int> vec;

	for (int i = 1; i <= 20; ++i) vec.push_back(i);

	cout << "Before: ";
	for (auto& tmp : vec) cout << tmp << " ";
	cout << "\n\n";

	// vec의 요소 중 isEven을 만족하지 않는 요소만큼 vec의 처음 위치부터 덮어 씌웁니다.
	// 값이 마지막으로 변경된 요소의 다음을 가리키는 반복자를 반환합니다.
	vector<int>::const_iterator it = std::remove_if(vec.begin(), vec.end(), isEven);

	cout << "After:  ";
	for (auto& tmp : vec) cout << tmp << " ";

	cout << "\n\n";
	cout << "Return value: " << *it << "\n";

	return 0;
}


결과)

 

설명)
1 ~ 20을 요소로 가지는 vec(반복자로)와 짝수일 때 참을 반환하는 isEven 함수를 인자로 전달합니다.
remove_if 함수는 함수를 만족하지 않을 경우 값의 복사를 진행하므로 홀수이면 vec의 첫 위치부터 복사합니다.
따라서 1~20중 10개의 홀수를 vec의 첫 위치부터 차례대로 덮어씁니다.

마지막으로 값이 마지막으로 변경된 부분(19)의 다음 요소를 가리키는 반복자를 반환합니다.
Return value는 반복자(반환값)가 가리키는 값을 출력하였습니다.  

 

참고)
http://www.cplusplus.com/reference/algorithm/remove_if/?kw=remove_if




댓글