본문 바로가기

카테고리 없음

C++ 벡터 특정 원소 지우는 방법 vector.erase(),remove() 등 Tips

반응형

1. Erase를 활용하는 방법

 

벡터 v에서 i번째 원소를 삭제하고 싶다면

erase 함수를 사용하면 된다.

erase 함수의 인자는 iterator 즉, 지우고 싶은 원소의 주소이다.

 

http://www.cplusplus.com/reference/vector/vector/erase/

 

 

vector::erase - C++ Reference

123456789101112131415161718192021222324 // erasing from vector #include #include int main () { std::vector myvector; // set some values (from 1 to 10) for (int i=1; i<=10; i++) myvector.push_back(i); // erase the 6th element myvector.erase (myvector.begin(

www.cplusplus.com

벡터 v의 시작 주소는 v.begin()이다. i번째 원소의 주소는 v.begin() + i 라고 하면 된다.

따라서 벡터 v의 i번째 인덱스에 있는 원소를 삭제하고 싶을 때에는

v.erase(v.begin() + i);

이렇게 쓰면 된다.

 

v[5]를 지우고 싶다면

v.erase(v.begin() + 5);

이렇게 하면 된다.

코드로 보자면 아래 코드를 실행하면

#include <iostream>
#include <vector>
using namespace std;

int main() {
	vector<int> v(10);
	for (int i = 0; i < 10; i++) {
		v[i] = i;
	}
	cout << "지우기 전:          ";
	for (int i = 0; i < v.size(); i++) {
		cout << v[i] << " ";
	}
	cout << endl;
	v.erase(v.begin() + 5);
	cout << "5번 인덱스 지운 후: ";
	for (int i = 0; i < v.size(); i++) {
		cout << v[i] << " ";
	}
	cout << endl;
	return 0;
}

다음과 같이 5번 인덱스에 저장되어 있던 5가 삭제된다.

벡터 클래스의 더 많은 함수들을 알고 싶다면 아래 링크에 있는 포스팅을 참고하면 된다.

 

 

2.Remove 활용하는 방법

 

연속 메모리 컨테이너(vector, deque, string)

- erase와 remove 합성문이 가장 좋은 방법이다.

 

양방향 반복자를 지원하는 list에도 통하지만, list는 remove를 사용하는 것이 좋다.

 

표준  연관 컨테이너일 때에는(set, multiset, map) remove라는 이름을 가진 어떤 것도 소용없다.

remove 알고리즘을 사용하면 컨테이너 값을 덮어써서 컨테이너를 변형시킬 수 있다.

하여간 안되고, 연관 컨테이너는 erase를 사용한다.(로그시간)

*시퀀스 컨테이너에 사용하는 remove 방법은 선형 시간.

연관 컨테이너의 erase는 상등성이 아닌 동등성에 기반하고 있다.

 

#include <iostream>
#include <vector>
#include <algorithm>
 
bool badValue(int x) 
{ 
    if ( x == 0)
    {
        std::cout<<"same 0"<<std::endl;
        return true;
    }
    return false; 
}
 
void main()
{
    std::vector<int> c;
    c.push_back(0);
    c.push_back(1);
    c.push_back(2);
    c.push_back(0);
    c.push_back(10);
 
    std::cout<<"vector size = "<<c.size()<<std::endl;
 
    c.erase(std::remove_if(c.begin(), c.end(), badValue), c.end());
 
    std::cout<<"vector size = "<<c.size()<<std::endl;
 
    for (int i : c)
    {
        std::cout<<i<<" "<<std::endl;
    }
}

 

 

 

참고----------------------------------------------------------------------------------

 

정리

 

컨테이너에서 특정한 값을 가진 객체를 모두 없애려면?

- vector, string, deque이면 erase-remove

- list이면 list::remove

- 표준 연관 컨테이너면? erase 멤버 함수

 

컨테이너에서 특정한 술어 구문을 만족하는 객체를 모두 없애려면?

- vector, string, deque이면 erase-remove_if 합성문을 사용한다.

- 컨테이너가 list이면 list::remove_if를 쓴다.

- 컨테이너가 표준 연관 컨테이너면? remove_copy_if와 swap을 쓰던가,

컨테이너 내부를 도는 루프에서 erase를 호출하면서 erase에 넘기는 반복자를 후위 증가 연산자로 증가시킨다.

 

루프 안에서 무엇인가를 하려면?

표준 시퀀스 컨테이너

- 컨테이너 요소를 하나씩 사용하는 루프를 작성한다.

- erase를 호출할 때마다 그 함수의 반환값으로 반복자를 업데이트하는 일을 꼭 해야한다.

 

표준 연관 컨테이너

- 컨테이너 요소를 하나씩 사용하는 루프를 작성한다.

- erase를 호출하면서 erase에 넘기는 반복자를 후위 증가 연산자로 증가시킨다.

 

참고 및 출처 :[effective STL]

반응형