检查列表和运行处理程序

时间:2008-10-28 01:19:55

标签: c++ c idioms

我发现自己编写的代码看起来很多:

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...
    }
}

我最终编写此代码的原因是,即使我收到多个可能导致它们运行的​​密钥代码,我也只需要在第二个循环中运行一次函数。

这似乎不是最好的方法。有更简洁的方式吗?

4 个答案:

答案 0 :(得分:2)

一种方法是维护从字符串到布尔值的映射。主要逻辑可以从以下内容开始:

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

然后,您可以在识别代码后立即执行相应的操作。

另一种方法是将可执行文件(对象,函数指针等)存储到某种“待办事项列表”中。例如:

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

初始化codefor以包含适用于每个代码值的函数指针或从公共基类子类化的对象。如果相同的代码出现多次,则todo中的相应条目将被覆盖与其已有的相同值。最后,迭代todo并运行其所有成员。

答案 1 :(得分:1)

由于您似乎并不关心集合中的实际值,因此可以使用int中的设置位替换它。您还可以使用日志时间搜索逻辑替换线性时间搜索逻辑。这是最终的代码:

// 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...

答案 2 :(得分:1)

它肯定不整洁,但你可以保留一组标志,说明你是否已经调用了该特定功能。这样你就可以避免在一组中保存,只需要标记。

由于(可能是从编写它的方式),修复了不同if / else块的编译时编号,你可以用bitset很容易地做到这一点。

答案 3 :(得分:0)

显然,这取决于具体情况,但最好让你调用的函数跟踪它们是否已经运行并在需要时提前退出。