2017-10-10 7 views
2

주어진 서명이있는 함수에서, 시퀀스의 요소를 [first, last]와 같은 방식으로 재정렬하고, 술어를 만족하는 모든 요소가 반복자를 반환하지 않는 요소 앞에 배치하고 주어진 술어를 만족하지 않는 첫번째 요소. 현재 요소가 술어를 충족 같은 위치에 새로운 요소가 그것을 만족하면 다시 마지막 반복자를 사용하여 술어별로 재정렬하기

  • 검사로 교체하지 않을 경우

    내 알고리즘은

      시퀀스를 반복
    • 시작
    • 입니다
    • (last-1)로 바꾸지 않으면 Yes로 진행하십시오.
    • 이미 교체 한 항목 중 하나에 도달 할 때까지 반복하십시오.

    내 코드

    template<class Iterator, class Predicate> 
    Iterator Rearrange(Iterator first, Iterator last, Predicate pred) { 
        auto res = first; 
        if (first == last) { 
        ; 
        } 
        else { 
        auto run = first; 
        auto end = last; 
        auto tmp = *first; 
        while (run != end) { 
         if (pred(*run) == false) { 
         again: tmp = *(--end); 
        *end = *run; 
        *run = tmp; 
        if (pred(*run) == false) { 
         goto again; 
        } 
         } 
         ++run; 
        } 
        } 
        return res; 
    } 
    

    그것은 나에게 내가 발견하고 이해할 수없는

    terminate called after throwing an instance of 'std::range_error' 
        what(): dereferencing end of sequence 
    Aborted 
    

    을 제공합니다. 즉, 컨테이너 밖에서 요소를 역 참조하려고 시도하는 곳에서 읽을 수는 있지만 프로그램에서 볼 수는 없습니다. 아무도 내가 코딩 오류를 수정하거나 내 알고리즘의 논리를 개선하는 데 도움이 될 수 있습니까?

  • +1

    18 년 전, VB6에서 C++로 이동 한 다음 C#으로 'goto'를 다시 처리하지 않아도되기를 기대했습니다. – Steve

    답변

    3

    입력 범위가 비어 있지 않고 해당 요소가 조건을 충족시키지 않으면 코드가 goto 루프에 걸려 다시 while에 도달하지 않습니다. 결국 --endfirst 전에 end이됩니다.

    학습 연습 인 경우 goto을 제거하는 것이 좋습니다. 당신은 나쁜 습관을 배우고 싶지 않고 goto은 희귀 한 합법적 인 용도를 가질 수 있지만 루프를 대체하는 것은 그 중 하나가 아닙니다. 또한 tmp의 춤은 std::swap으로 바꿀 수 있습니다.

    학습 연습이 아닌 경우 원하는대로 정확히 std::partition을 사용하십시오.