ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [33] - Remove_if
    Graphics 2021. 8. 9. 14:37

    Ref

    1. (https://en.cppreference.com/w/cpp/algorithm/remove)

    std::copy에 이어서 유용하게 쓸 수 있습니다. 정의는 다음과 같이 되어 있습니다.

    일반적으로 삭제를 감행할 Container이든 무엇이든 범위를 주고 predicate를 설정합니다. 사용법은 마치 copy_if와 다르지 않은 것처럼 느껴집니다. 참고로 Predicate는 boolean을 반환해야 합니다.

    이 함수의 작동 방식을 vector를 통해 설명할 수 있습니다. { 1, 2, 3, 4, 5, 6, 7, 8, 9 } 를 격납하고 있는 vector가 있다고 가정하고 2,3,5,7을 제거한다 하면 iterator는 1부터 시작해서 각 원소에 대해 Predicate를 검증합니다. 1은 넘어가고 2를 제거하면 다른 iterator가 사라진 2를 가리키게 됩니다. 다시 3을 검증하고 사라지게 만들고 4를 검증했을 때, 이는 Predicate에 검증해서 false를 받아서 제거하지 않습니다. 대신에 처음 사라졌던 2의 위치에 이 4의 값을 넣고 제거된 자리를 가리키던 Iterator를 다음 제거된 자리를 가리키도록 합니다. 이 과정을 9까지 반복하고 반환하는 값은 새롭게 만들어진 vector의 끝입니다. 그런데 Vector의 크기 자체가 줄어드는 것은 아니고 제거된 값들이 vector의 끝에 몰려있을 뿐이므로 erase함수를 통해 벡터의 쓰레기 값을 격납한 섹션을 잘라내는 편이 안전합니다. 이 remove_if함수가 직접 격납된 쓰레기 값을 제거하지 않는 이유는 해당 함수level에서는 Container라는 개념이 없기 때문입니다.

    그런데 곰곰이 생각해 보았을 때, 정렬의 문제가 발생합니다. 첫 번째에 기술한 방법처럼 삭제를 하고 빈 자리가 보일 때마다 계속 바꾸는 방식을 채택하면 충분히 많은 양의 원소에 대해서 어마어마한 Running time을 발생시키게 됩니다. 그래서 원소의 정렬을 고려하지 않고 벡터의 처음부터 끝까지 Predicate에 대해서 검증을 끝마치고 빈 자리마다 Vector의 끝에서 하나 씩 move하는 알고리즘을 사용할 수도 있습니다. 그 이후에 정렬이 반드시 필요하다면 적합한 정렬 알고리즘을 수행하는 편이 나을 것입니다. 이전 std::copy에서 썼던 코드를 그대로 활용하도록 하겠습니다. 만들어 볼 것은 알파벳 'E', 'e'가 포함되지 않은 문자를 제거하는 함수를 만들어 볼 것입니다.

    예상을 하길, Funf와 Acht가 사라질 것입니다.

    사라졌습니다

    remove_copy_if라든가 remove_copy가 있긴 한데 거의 쓸 일이 없습니다. 그 이유는 std::remove의 활용에 불과하기 때문입니다. 언뜻 보기에 대단히 방대한 양의 Standard Library이지만 이런 식으로 내용 자체가 비슷비슷한 경우가 상당히 많아서 실질적으로 체득해야 할 함수의 양은 크게 줄어듭니다.

    std::unique

     

    함수의 설명을 보면 첫 번째로 마주치는 어떤 원소를 제외하고 그것과 같은 원소들을 제거한다고 되어 있습니다. 어떤 결과를 내는지는 코드를 직접 짜보는 편이 나을 것 같습니다.

    결과를 보니 중복이 되더라도 연속하지 않으면 제거하지 않는다는 사실을 알 수 있습니다. 즉, Funf가 여러 번 연속해서 반복되면 제거를 해버리지만 그것이 연속되지 않는다면 제거하지 않습니다. 즉, std::unique는 Container 내부에 모든 원소가 유일하게 만들어주는 기능은 수행할 수 없다는 사실입니다. 그러면 std::unique_copy가 하는 일도 자명합니다. 추측하건데 연속적이지 않은 원소에 대해서 복사를 수행할 것입니다. 만약 위의 예제에서 a를 c에 대해 복사한다면 결과도 반드시 같을 것입니다.

    같습니다. 여기서 그치지 않고 직접 function template를 작성하여 utility function을 만들 수도 있습니다.

    결과는 이전에 만들었던 함수와 완전히 같을 겁니다.

Designed by Tistory.