[c++] std :: map에서 항목을 필터링하는 방법?



1 Answers

Mark Ransom 알고리즘의 변형이지만 일시적인 필요성은 없습니다.

for(Actions::iterator it = _actions.begin();it != _actions.end();)
{
    if (expired(*it))
    {
        bar(*it);
        _actions.erase(it++);  // Note the post increment here.
                               // This increments 'it' and returns a copy of
                               // the original 'it' to be used by erase()
    }
    else
    {
        ++it;  // Use Pre-Increment here as it is more effecient
               // Because no copy of it is required.
    }
}
Question

나는 대략 다음 코드를 가지고있다. 이것이 더 좋거나 더 효율적으로 만들어 질 수 있을까요? 아마도 std::remove_if 있을까요? 그것을 가로 지르는 동안지도에서 항목을 제거 할 수 있습니까? 임시지도 사용을 피할 수 있습니까?

typedef std::map<Action, What> Actions;
static Actions _actions;

bool expired(const Actions::value_type &action)
{
  return <something>;
}

void bar(const Actions::value_type &action)
{
  // do some stuff
}

void foo()
{
  // loop the actions finding expired items
  Actions actions;
  BOOST_FOREACH(Actions::value_type &action, _actions)
  {
    if (expired(action))
      bar(action);
    else
      actions[action.first]=action.second;
    }
  }
  actions.swap(_actions);
}



만료 된 항목을 제거하는 것이 좋습니다. map::erase 사용하지 않는 이유는 무엇입니까? 이렇게하면 더 이상 필요하지 않은 요소 만 제거하고 유지하려는 모든 요소가있는 전체 복사본을 다시 작성하지 않아도됩니다.

이렇게하는 방법은 삭제할 요소를 가리키는 반복자를 제외하고 반복이 끝난 후 모두 지우는 것입니다.

또는 방문한 요소를 저장하고 다음 요소로 이동 한 다음 임시 요소를 지울 수 있습니다. 루프 경계는 귀하의 경우 엉망이되어 버리므로 반복을 스스로 미세 조정해야합니다.

만료 ()가 구현되는 방식에 따라 다른 더 좋은 방법이있을 수 있습니다. 예를 들어, 타임 스탬프를 맵의 키로 추적하고 있다면 (expired ()가 의미하는 것처럼?), 현재 타임 스탬프에서 upper_bound를 수행 할 수 있으며 [begin (), upper_bound ()) 범위의 모든 요소는 처리 및 지울 수 있습니다.



Related