티스토리 툴바


Container<int> c;
라는 컨테이너가 있을때

1963이라는 값을 가진것을 모두 지우고 싶다면

연속 메모리 컨테이너(vector, deque, string)의 경우에 가장 좋은 방법은 erase-remove 합성문이다.
 
erase( remove(c.begin(), c.end(), 1963), c.end()); 
// 컨테이너가 vector, string 혹은 deque일 때 특정한 값을 가진 요소를 없애는
// 가장 좋은 방법은 erase-remove 합성문을 사용하는 것이다.

이 방법은 양방향 반복자를 지원하는 list에도 통하지만, list의 경우엔 멤버함수인 remove가 더 효율적이다.
 
c.remove(1963);
// 컨테이너가 list일 때에는 remove 멤버함수가 특정한 값을 가진 요소를 모두 없애는 데에 더 좋다.

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

멤버함수로는 remove가 없을뿐더러 remove를 사용하면 컨테이너에 값을 덮어써서 컨테이너가 변형된다.

연관컨테이너에서 특정한 값을 가진 요소를 지울땐 erase를 사용한다.

c.erase(1963);
// 컨테이너가 표준 연관 컨테이너일 때에는 erase 멤버 함수가 특정한 값을 가진 요소를
// 모두 없애는 데에 가장 좋다.

이렇게 하면 삭제도 제대로되고 효율적이다.

여기서 특정한 값을 가진 요소를 모두 없애지 않고다음의 술어구문이 true를 반환하는 요소를 모두 없앤다고 할때
 
bool badValue(int x);  // x가 "나쁘다"면 true를 반환합니다.

c.erase( remove_if(c.begin(), c.end(), badValue), c.end());
// 컨테이너가 vector, string, deque일 때 badValue가
// true를 반환하는 요소를 모두 없애는 가장 좋은 방법입니다.

c.remove_if(badValue);
// 컨테이너가 list일 때 badValue가 true를 반환하는 요소를
// 모두 없애는 가장 좋은 방법입니다.

표준 연관 컨테이너의 경우(set, map 등)
이렇게 쉽게 문제가 해결되지는 않는다.
따라서 처음부터 끝까지 도는 루프를 넣어서 요소를 직접 검사해서 지워야 한다.
이 작업은 소스코드도 간단하다.

Container c;
...
for(Container::iterator i = c.begin(); i != c.end(); /* 비어있음 */)
// for 루프의3번째 부분이 비어있고 아래쪽에서 증가된다.
{
    if(badValue(*i)) // i가 가리키는 값이 "나쁜값"이면
        c.erase( i++ ); // 후위증가에 의해 i를 증가시킨다.
    else
        ++i;
}

만약 vector, string, deque로 루프를 도는 중간에 erase를 해야 하는 상황이 생긴다면 이렇게 바꾸면 된다.

for(Container::iterator i = c.begin(); i!= c.end(); /* 비어있음 */)
{
    ...
    ...
    ...

    if(badValue(*i)
    {
        i = c.erase(i); // erase의 반환값을 i에 저장해서 반복자의 유효성을 유지시킨다.
    }
    else
    {
        ++i;
    }
}

이 글은 이펙티브 STL 책을 참고하여 작성하였으며, 만약 저작권적으로 문제가 된다면 댓글등으로 삭제요청하시면 삭제조치 하도록 하겠습니다.
Posted by 세카이 세카이_

댓글을 달아 주세요


http://sdmeter.tistory.com  <= 여기 블로그는 따로 있습니다.
Posted by 세카이 세카이_

댓글을 달아 주세요


출처 카페 > C언어를 배우자 | 라온
원문 http://cafe.naver.com/cafec/505
말이 좀 어려운 것 같은데 그냥 훑어 보세요. 프로그램 해 보면 차츰 익숙해 질겁니다.

예제를 만들어 하나씩 살펴보고 직접 해보시면 꽤 간단하게 프로그램이 만들어 지는 것을 경험 하실 겁니다. 우선 STL에 대해 살펴 보겠습니다.

STL에는 6가지의 주요 component가 있습니다.

1. container : data set 이라고 생각하시면 쉽게 이해 됩니다.

2. generic algorithm : <algorithm> 과 container 자체에 있는 Algorithm 입니다.

3. iterator : C/C++의 포인터와 같이 Conatiner의 요소를 지정할 수 있는 객체입니다.

container를 잘 사용할려면 반드시 알아야 합니다.

보통 서적에서는 반복자라는 말을 쓰던데 특성을 보고 이름을 그리 붙인것 같습니다.

4. function object : accumlate 같은 것인데 그리 범용이라고 보기는 힘들지만..

5. adaptor : component의 interface를 변경하는 component입니다.

6. allocator : 할당기라고 하는데요. STL container는 allocator class를 사용하여 프로그램에서

사용하고 있는 메모리 할당 관련 정보를 캡슐화 하고 있습니다.

우선 Container를 보구요 다른 내용은 예제로 자세히 보는 것이 좋을 것 같습니다.

아래 내용은 STL Tutorial and Reference Guide 2nd 내용입니다.

Container

객체들의 컬렉션을 저장하고 있는 객체를 STL에서는 컨테이너라고 합니다.

두가지 종류가 있는데 Sequence Container , Sorted Associative Container 입니다.

Sequence Container : 타입이 동일한 객체들을 선형으로 구성한 컬렉션

- vector<T> : 가변길이 시퀀스를 임의 접근 할 수 있으며, 시퀀스 맨 끝에서 수행되는 삽입과

삭제는 아모타이즈드 상수 시간에 수행이 가능합니다.

참고 : 임의접근(random access)이 가능하다는 것은 시퀀스 i 번째 원소를 접근하는데 걸리

는 시간이 상수 시간이라는 것을 의미합니다. 이는 몇 번째이건 관계없이 항상 일정 하다는

것입니다.

- deque<T> : 가변길이 시퀀스를 임의 접근 할 수 있으며 시퀀스 맨 앞과 맨 끝에서 수행되는

삽입과 삭제는 모두 아모타이즈드 상수 시간에 수행이 가능합니다.

- list<T> : 가변길이 시퀀스에 대해서 선형 시간 접근만이 가능하며, 삽입과 삭제는 시퀀스 내

에서라면 어디서든지 상수 시간 내에 수행이 가능합니다.

Sorted Associative Container : 주어진 키로 컬렉션에서 객체를 신속하게 찾을 수 있는

기능을 제공합니다. 컬렉션의 사이즈는 실행시에 변할 수 있고 네 가지 타입이 있습니다.

- set<Key> : 유일키를 지원하며, 원하는 키를 신속하게 찾아 냅니다.

- multiset<Key> : 중복키를 지원하며, 원하는 키를 신속하게 찾아 냅니다.

- map<Key, T> : 유일키를 지원하며, 주어진 키로 원하는 객체를 신속하게 찾아 냅니다.

- multimap<Key, T> : 중복키를 지원하며, 주어진 키로 원하는 객체를 신속하게 찾아 냅니다.


STL Component

 

STL Container Types

Posted by 세카이 세카이_

댓글을 달아 주세요