컨테이너에서 요소를 삭제할때 erase 멤버함수를 쓰곤 한다.
그런데 remove 라는 것도 있는데 이건뭔가?
remove 는 알고리즘이다. (주)list 의 경우에는 멤버함수 remove 도 있다.
erase 와 remove 의 차이는 뭘까?
[remove 알고리즘은 일치하는 모든 요소를 삭제한다.]
소스를 보자.
vector<int> v;
v.reserve(10); // 재할당을 피하기위해서 입니다.
for( int i = 0; i <= 10; ++i )
v.push_back(i);
cout << v.size(); // 10을 출력합니다.
v[3] = v[5] = v[9] = 99;
remove( v.begin(), v.end(), 99 ); // 99 란 값을 가진 요소를 모두 remove 합니다.
cout << v.size(); // 앗, 여전히 10입니다!
[remove 는 어느것도 "진짜로" 없애지 않는다. 없앨 수 없기 때문이다.] <- 기억해주세요
그림을 보면서 이해해보자.
remove 를 호출하기 전의 모습이다.
vector<int>::iterator newEnd( remove( v.begin(), v.end(), 99 ) );
실제로는 삭제를 수행하지 않고 뒤쪽의 요소를 앞쪽으로 덮어써 버리는 과정을 거치고나서 뒤쪽의 영역을 무효화한다.
그래서 remove 알고리즘을 사용한 컨테이너는 개수가 줄어들지 않는다.
? 는 사실 다음과 같다.
실제 동작은 범위를 훑어가면서 "제거될" 요소의 위치에 뒤에있는 "그대로 유지될" 요소의 값을 덮어씌우는 것이다.
이때 생기는 무효한 범위( 8, 9, 99 )는 erase 멤버함수를 써서 직접 지워야한다.
remove 알고리즘은 무효한 영역의 시작을 가리키는 반복자( newEnd )를 반환하기 때문에 다음과 같이 해주면 된다.
연속메모리 컨테이너(vector, deque, string)의 경우
v.erase( remove(v.begin(), v.end(), 1234), v.end() );
(주)
list 경우, 이 두 작업이 하나로 합쳐진
l.remove(1234);
를 쓰면 된다.
연관 컨테이너(set, map, multi-)의 경우
c.erase(1234);
로 해주면 같은 동작을 한다.
<출처 : http://h2ostudio.egloos.com/4343561>