2011-10-11 4 views
1

컨테이너의 값 범위를 지우는 함수를 구현해야합니다. 그래서 예를 들어C++ 벡터; remove_if 하나의 값만 제거 하시겠습니까?

eraseRange(v, 1.5, 24); 

는 1.5 컨테이너 V 미만 24보다 큰 값을 삭제할 것입니다 그리고 내 기능은 내가 사용하는 목록, 완벽하게 작동합니다.

container.erase(remove_if(container.begin(), container.end(), rg)); 

어디 RG 검사가 있다면 그 범위 안에서 (그 부분의 구현은 문제가 아니므로, 나는 그것에 대해 자세히 설명하지 않을 것이다).

그러나 벡터에 대해 eraseRange를 호출하고 유사한 방법을 사용하여 값을 지우면 첫 번째 값만 지워집니다. 그래서 1에서 10까지의 숫자를 가진 벡터를 가지고 있다면 :

eraseRange(v, 3, 7); 

3 개만 삭제됩니다.

이제는 일반적으로 문제가되지 않으므로 값을 확인하기 위해 반복기를 사용합니다. 이 특정 연습을 제외하고 for/while/do 루프는 명시 적으로 금지되어 있습니다 ...

따라서 문제는 임의 액세스 반복기가있는 컨테이너의 문제인 것 같습니다. 그리고 대안으로 무엇을 구현해야할지 모르겠습니다. 도움?

답변

10

erase의 몇 가지 오버로드가 있습니다.

하나의 과부하는 사용중인 하나의 반복자를 사용하여 반복기가 가리키는 요소를 지 웁니다.

사용되어야 다른 오버로드는 범위 (한쌍의 반복자를) 받아 범위 내의 모든 요소를 ​​삭제합니다 :

c.erase(remove_if(c.begin(), c.end(), rg), c.end()); 
             ^^^^^^^^^ 

[잘 모르겠어요 왜 코드 " 당신이 말하는 것처럼, 목록을 완벽하게 작동합니다. std::list에는 erase의 두 가지 오버로드가 있습니다. std::list에는 std::list (즉, std::list이 링크 된 목록으로 구현되었으므로 실제로는 개체를 이동하지 않고 지우기/제거를 구현할 수 있기 때문에)에 맞게 특별히 최적화 된 지우기/제거 알고리즘을 더 잘 구현할 수있는 멤버 함수 remove_if이 있습니다.]

+0

고마워요! 내가 필요한 것. – Fault

1

remove_if은 "새로운 마지막"으로 단일 반복기를 반환합니다. 그것은 벡터에서 과거의 새로운 것을 마지막으로 귀하의 술어를 만족시키는 모든 것을 뒤섞습니다. 새로운 마지막 전의 모든 것은 귀하의 술어를 만족시키지 못합니다. 벡터의 단일 항목에 대해서만 erase을 실행 중이므로 새로운 마지막 항목 만 제거합니다. 이는 조건부를 만족시키는 유일한 것입니다. 대신 당신은 당신의 술어를 만족시키는 모든 것 인 새로운 마지막에서부터 모든 것을 지우고 싶습니다.

container.erase(
    remove_if(container.begin(), container.end(), rg), 
    container.end() 
);