在嵌套循环/循环不变量中检查一次

Check something once in nested loop / loop-invariants

本文关键字:一次 检查 嵌套循环 循环 不变量      更新时间:2023-10-16

在嵌套循环中每次迭代只做一次的最聪明的方法是什么?我无法取出不变部分,因为外循环非常复杂。这是我的C++示例:

void foo::bar() {
    if(oldCycle == tree.cycle) {
        doSomething();
        oldCycle++;
    }
}

在tree.cycle递增之前,经常调用此方法。oldCycle是foo 的私有成员变量

claas foo {
public: ...
private:
int oldCycle;
};

编译器会优化这个代码吗?还是每次迭代都会运行if检查?

编辑:这里类似于请求的带有循环的代码:第一个循环是在mexFunction()方法中,该算法在matlab中启动并调用mexFunction。

void mexFunction(...) {
    for( tree.cycle = 0; tree.cycle<maxIt; tree.cycle++ ) {
        foo->startfoo();
    }
}

这是另一个循环:

void foo::startfoo() {
    for(tree.cur_it = 0; tree.cur_it <=39; tree.cur_it++ ) {
        bar();
    }
}

对于一般情况,您无法真正优化它,因为您需要以某种方式从集合中删除特殊情况。

但是,对于特殊处理第一个元素的特殊情况(例如,当将带有de­li­mit­ers的范围打印为"1, 2, 3"时),可以使用Knuth的"环半":

Naive循环:

for (unsigned int i = 0; i != values.size(); ++i)
{
    if (i != 0) { std::cout << ", "; }
    std::cout << values[i];
}

循环半:

if (!values.empty())
{
    for (unsigned int i = 0; ; )
    {
        std::cout << values[i];
        ++i;
        if (i == values.size()) { break; }
        std::cout << ", ";
    }
}

后一种构造更为复杂,但省去了大部分错误的检查i != 0

也就是说,即使你以天真的方式编写代码,一个好的编译器也会进行部分展开,这是很有可能的。

对于简单的情况,我更喜欢这种方法。

if ( ! values.empty())
{
    std::cout << values[0];
    for (size_t z = 1; z < values.size(); z++)
    {
        std::cout << ", " << values[z];
    }
}