سؤال

وأجد نفسي كتابة التعليمات البرمجية التي يشبه هذا كثيرا:

set<int> affected_items;
while (string code = GetKeyCodeFromSomewhere())
{
    if (code == "some constant" || code == "some other constant") {
        affected_items.insert(some_constant_id);
    } else if (code == "yet another constant" || code == "the constant I didn't mention yet") {
        affected_items.insert(some_other_constant_id);
    } // else if etc...
}
for (set<int>::iterator it = affected_items.begin(); it != affected_items.end(); it++)
{
    switch(*it)
    {
        case some_constant_id:
           RunSomeFunction(with, these, params);
        break;
        case some_other_constant_id:
           RunSomeOtherFunction(with, these, other, params);
        break;
        // etc...
    }
}

والسبب أنا في نهاية المطاف كتابة هذا الرمز هو أنني بحاجة لتشغيل فقط وظائف في الحلقة الثانية مرة واحدة حتى لو كنت قد تلقيت عدة رموز الرئيسية التي قد تسبب لهم لتشغيل.

وهذا فقط لا يبدو أفضل طريقة للقيام بذلك. هل هناك طريقة أكثر إتقانا؟

هل كانت مفيدة؟

المحلول

ومنذ كنت لا يبدو أن نهتم القيم الفعلية في مجموعة يمكن استبدالها مع وضع بت في عدد صحيح. يمكنك أيضا استبدال الوقت منطق البحث الخطي مع منطق البحث في الوقت السجل. هنا هو رمز النهائي:

// Ahead of time you build a static map from your strings to bit values.
std::map< std::string, int > codesToValues;
codesToValues[ "some constant" ] = 1;
codesToValues[ "some other constant" ] = 1;
codesToValues[ "yet another constant" ] = 2;
codesToValues[ "the constant I didn't mention yet" ] = 2;

// When you want to do your work
int affected_items = 0;
while (string code = GetKeyCodeFromSomewhere())
    affected_items |= codesToValues[ code ];

if( affected_items & 1 )
    RunSomeFunction(with, these, params);
if( affected_items & 2 )
    RunSomeOtherFunction(with, these, other, params);
// etc...

نصائح أخرى

ونهج واحد هو الحفاظ على خريطة من السلاسل إلى القيم المنطقية. منطق الرئيسي يمكن أن تبدأ مع شيء من هذا القبيل:

if(done[code])
    continue;
done[code] = true;

وبعد ذلك يمكنك تنفيذ الإجراءات المناسبة بمجرد تحديد رمز.

وثمة نهج آخر هو لتخزين شيء قابل للتنفيذ (كائن، مؤشر وظيفة، أيا كان) إلى نوع من "القيام قائمة." على سبيل المثال:

while (string code = GetKeyCodeFromSomewhere())
{
    todo[code] = codefor[code];
}

وتهيئة codefor لاحتواء المؤشر المناسب وظيفة، أو كائن subclassed من الفئة الأساسية المشتركة، لكل قيمة التعليمات البرمجية. إذا يظهر رمز نفسه أكثر من مرة واحدة، وإدخال المناسب في ما يجب عمله فقط الحصول على الكتابة بنفس القيمة التي لديها بالفعل. في النهاية، أعاد على ما يجب عمله وتشغيل جميع أعضائها.

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

وأنه ليس هناك (ويفترض من الطريق هو مكتوب)، وهي ثابتة في وقت الترجمة عدد من مختلف إذا / كتل شيء آخر، يمكنك القيام بذلك بسهولة جدا مع bitset.

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

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