std ::지도를 통한 루프에서 마지막 반복을 어떻게 감지 할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/151046

  •  02-07-2019
  •  | 
  •  

문제

다음과 같은 작업을 수행하기 위해지도를 통해 루프를 마지막으로 반복하는지 여부를 결정하는 가장 좋은 방법을 찾으려고 노력하고 있습니다.

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    bool last_iteration;
    // do something for all iterations
    if (!last_iteration) {
        // do something for all but the last iteration
    }
}

이 작업을 수행하는 몇 가지 방법이있는 것 같습니다 : 임의의 액세스 반복자, distance 기능 등. 표준 방법은 무엇입니까?

편집 :지도 용 임의의 액세스 반복자가 없습니다!

도움이 되었습니까?

해결책

정지? 나는 그것을 주장 할 수 없지만 제안 할 것입니다

final_iter = someMap.end();
--final_iter;
if (iter != final_iter) ...

편집 제안한대로 수정합니다 KTC. (감사합니다! 때때로 당신은 너무 빨리 가서 가장 간단한 것들을 엉망으로 만들었습니다 ...)

다른 팁

C ++ 11이므로 std :: next ()를 사용할 수도 있습니다.

   for (auto iter = someMap.begin(); iter != someMap.end(); ++iter) { 
        // do something for all iterations
        if (std::next(iter) != someMap.end()) {
            // do something for all but the last iteration
        }
    }

질문이 얼마 전에 질문을 받았지만, 나는 그것이 공유 할 가치가 있다고 생각했습니다.

이것은 가장 간단한 것 같습니다.

bool last_iteration = iter == (--someMap.end());

Forweriterator를 사용하려면 다음과 같습니다.

for ( i = c.begin(); i != c.end(); ) {
        iterator cur = i++;
        // do something, using cur
        if ( i != c.end() ) {
                // do something using cur for all but the last iteration
        }
}

수정 된 Mark Ransom은 실제로 의도 한대로 작동합니다.

finalIter = someMap.end();
--finalIter;
if (iter != final_iter)

아직 아무도 언급하지 않았지만 물론 부스트는 무언가를 가지고 있습니다.)

boost.next (및 동등한 부스트.

예제는 다음과 같습니다.

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    // do something for all iterations
    if (boost::next(iter) != someMap.end()) {
        // do something for all but the last iteration
    }
}

다음 코드는 컴파일러에 의해 최적화되므로 OOP 규칙뿐만 아니라 성능에 의해이 작업에 가장 적합한 솔루션이되도록합니다.

if (&*it == &*someMap.rbegin()) {
    //the last iteration
}

std :: map은 다음과 같은 코드에 대한 특수 회원 함수 rbegin을 받았기 때문에 OOP 규칙에 따른 최고의 코드입니다.

final_iter = someMap.end();
--final_iter;
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <algorithm>

using namespace boost::lambda;

// call the function foo on each element but the last...
if( !someMap.empty() )
{
  std::for_each( someMap.begin(), --someMap.end(), bind( &Foo, _1 ) );
}

std :: for_each를 사용하면 루프가 빡빡하고 정확한지 확인합니다 ... 단일 인수를 취하는 함수 foo ()의 도입 (유형은 Somemap에 포함 된 내용과 일치해야 함). 이 접근법은 1 라인이 추가되었습니다. 물론 FOO가 실제로 작 으면 Lambda 기능을 사용하고 & foo에 대한 호출을 제거 할 수 있습니다.

당신이 그것에 무언가를주지 않도록 EOF를 찾기 위해 일하는 이유.

간단히 말해서 배제하십시오.

for (iter = someMap.begin(); someMap.end() - 1; ++iter) {
    //apply to all from begin to second last element
}

키스 (간단하게 유지)

간단하고 효과적인 접근 방식 :

  size_t items_remaining = someMap.size();

  for (iter = someMap.begin(); iter != someMap.end(); iter++) {
    bool last_iteration = items_remaining-- == 1;
  }

내 최적화 된 테이크는 다음과 같습니다.

iter = someMap.begin();

do {
    // Note that curr = iter++ may involve up to three copy operations
    curr = iter;

    // Do stuff with curr

    if (++iter == someMap.end()) {
        // Oh, this was the last iteration
        break;
    }

    // Do more stuff with curr

} while (true);

어때요, 아무도 언급하지 않았지만 ...

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
    // do something for all iterations
    if (iter != --someMap.end()) {
        // do something for all but the last iteration
    }
}

이것은 간단 해 보인다, MM ...

전체 프로그램 :

#include <iostream>
#include <list>

void process(int ii)
{
   std::cout << " " << ii;
}

int main(void)
{
   std::list<int> ll;

   ll.push_back(1);
   ll.push_back(2);
   ll.push_back(3);
   ll.push_back(4);
   ll.push_back(5);
   ll.push_back(6);

   std::list<int>::iterator iter = ll.begin();
   if (iter != ll.end())
   {
      std::list<int>::iterator lastIter = iter;
      ++ iter;
      while (iter != ll.end())
      {
         process(*lastIter);
         lastIter = iter;
         ++ iter;
      }
      // todo: think if you need to process *lastIter
      std::cout << " | last:";
      process(*lastIter);
   }

   std::cout << std::endl;

   return 0;
}

이 프로그램은 다음과 같습니다.

 1 2 3 4 5 | last: 6

반복 전에 맵에서 요소를 꺼낸 다음 "마지막 반복"을 루프에서 수행 한 다음 요소를 다시 넣을 수 있습니다. ~ 안으로 지도. 이것은 비동기 코드의 경우 끔찍하게 나쁘지만 C ++의 나머지 부분이 동시성에 얼마나 나쁜지를 고려할 때 문제가 될 것이라고 생각하지 않습니다. :-)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top