简化C++中的嵌套循环结构

Simplify a nested loop structure in C++

本文关键字:嵌套循环 结构 C++ 简化      更新时间:2023-10-16

>我在一个程序中发现了一个嵌套的循环结构,它看起来像下面的简化版本。变量empty_count是在到达外部循环之前估计的。然后循环尝试做一些事情来递减empty_count .但是,empty_count可能永远不会接近零,因此程序员认为:"只需至少运行一次内部循环,直到empty_count 不再改变,打破外环"。

在这里有点挣扎,因为在最好的情况下,我只想与 OpenMP 一起使用一个 for 循环。不确定这是否可能。

// empty_count = some_value
size_t last_count = 0;              // starting value is 0
while (last_count != empty_count)   // count as long as the counter changes in the inner loop
{
    last_count = empty_count;       // update the counter for the break condition
    for (size_t id = 0; id < array.size(); id++)
    {
        if(some_condition) continue;
        int foo = some_function();
        switch (foo) {
        case 0:
            continue;
        case 1:
            break;
        default:
            break;
        };
        empty_count--; // maybe never reached :/
    }
}

last_count必须与empty_count相同这一事实实际上只是一个标志,因此计数可以用标志代替。您可能需要处理循环前 some_value 为 0 的情况,这将导致循环无法在原始代码中运行。

接下来是最简单的更改,在不更改功能的情况下使代码稍微容易一些。 请注意,此示例简化时的开关实际上相当无用,所以我也替换了它。

bool nextloopFlag = true;             // starting value is 0
while (nextloopFlag)   // count as long as the counter changes in the inner loop
{
    nextloopFlag = false;
    for (size_t id = 0; id < array.size(); id++)
    {
        if (some_condition) continue;
        if (some_function() == 0) continue;
        nextloopFlag = true;
    }
}

为了避免该标志,有时使用 goto 跳出嵌套循环。 这是否更好存在一些争论。 在这种情况下,goto 会立即跳出内部循环,因此它不会与原始代码相同。

我希望这有助于最终将其恢复为 1 个循环。

循环的主体:

        if(some_condition) continue;
        int foo = some_function();
        switch (foo) {
        case 0:
            continue;
        case 1:
            break;
        default:
            break;
        };
        empty_count--; // maybe never reached :/

可以替换为:

        if(some_condition || some_function() == 0)
           // Do nothing
        else
           empty_count--; // may never be reached :/

如果不向我们展示条件和函数的更多细节,就不可能展示如何将其转换为单个循环。

这个呢?

void update(size_t& id, bool& flag, size_t sz)
{
    if (++id == sz && flag)
    {
        id = 0;  // repeat the loop
        flag = false;
    }
}
bool flag = false;
for (size_t id = 0; id < array.size(); update(id, flag, array.size()))
{
    if (some_condition || !some_function()) continue;
    flag = true;
}

(我没有测试这个,而是沿着这些思路简化为单个循环(

正如其他答案中提到的,在这种情况下,您甚至可能不需要继续语句:

bool flag = false;
for (size_t id = 0; id < array.size(); update(id, flag, array.size()))
{
    flag = flag || !(some_condition || !some_function());
}

您可以简化此代码:

 int foo = some_function();
    switch (foo) {
    case 0:
        continue;
    case 1:
        break;
    default:
        break;
 };

if (some_function() == 0) continue;