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

时间:2017-06-14 08:12:13

标签: c++

我在程序中找到了一个嵌套循环结构,它看起来像下面这样的简化版本。 在到达外循环之前估计变量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 :/
    }
}

4 个答案:

答案 0 :(得分:1)

您可以简化此代码:

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

if (some_function() == 0) continue;

答案 1 :(得分:1)

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循环。

答案 2 :(得分: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 :/

在没有向我们展示条件和功能的更多细节的情况下,无法显示如何将其转换为单个循环。

答案 3 :(得分:1)

这个怎么样?

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

(我没有对此进行测试,但是这些内容可以简化为单个循环)

正如其他答案所述,在这种情况下,您甚至可能不需要continue语句:

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