سؤال

لدي تقريبا الكود التالي.هل يمكن جعل هذا أجمل أو أكثر كفاءة؟ربما باستخدام 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);
}
هل كانت مفيدة؟

المحلول

يمكنك استخدام draw()، لكنني لا أعرف كيف سيتعامل BOOST_FOREACH مع المكرر الذي تم إبطاله.ال وثائق الخريطة :: محو ينص على أنه سيتم إبطال المكرر الذي تم مسحه فقط، ويجب أن يكون الآخرون على ما يرام.إليك كيفية إعادة هيكلة الحلقة الداخلية:

Actions::iterator it = _actions.begin();
while (it != _actions.end())
{
  if (expired(*it))
  {
    bar(*it);
    Actions::iterator toerase = it;
    ++it;
    _actions.erase(toerase);
  }
  else
    ++it;
}

نصائح أخرى

شكل مختلف من خوارزمية 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.
    }
}

الشيء الذي يبدو أن لا أحد يعرفه على الإطلاق هو أن المسح يُرجع مكررًا جديدًا ومضمونًا ليكون صالحًا، عند استخدامه في أي حاوية.

Actions::iterator it = _actions.begin();
while (it != _actions.end())
{
  if (expired(*it))
  {
    bar(*it);
    it = _actions::erase(it);
  }
  else
    ++it;
}

ربما لا يكون تخزين action.end() خطة جيدة في هذه الحالة نظرًا لأن استقرار المكرر غير مضمون، على ما أعتقد.

إذا كانت الفكرة هي إزالة العناصر منتهية الصلاحية، فلماذا لا تستخدمها الخريطة::محو؟بهذه الطريقة، كل ما عليك فعله هو إزالة العناصر التي لم تعد بحاجة إليها، وليس إعادة بناء نسخة كاملة بكل العناصر التي تريد الاحتفاظ بها.

الطريقة التي يمكنك بها القيام بذلك هي حفظ التكرارات التي تشير إلى العناصر التي تريد مسحها، ثم مسحها جميعًا بعد انتهاء التكرار.

أو يمكنك حفظ العنصر الذي قمت بزيارته، والانتقال إلى العنصر التالي، ثم مسح العنصر المؤقت.يتم العبث بحدود الحلقة في حالتك، لذا عليك ضبط التكرار بنفسك.

اعتمادًا على كيفية تنفيذ الدالة Expedid()‎، قد تكون هناك طرق أخرى أفضل.على سبيل المثال، إذا كنت تتبع الطابع الزمني كمفتاح للخريطة (كما تشير انتهاء الصلاحية ()؟)، فيمكنك القيام بـ Upper_bound على الطابع الزمني الحالي، وكل العناصر في النطاق [ begin(), Upper_bound() ) تحتاج إلى لتتم معالجتها ومحوها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top