c ++ vector不在嵌套for循环中更新

时间:2011-06-30 21:49:47

标签: c++ vector for-loop nested

所以我创建并初始化一个矢量(大小为nmask + 3)为0,并为其中一个元素分配一个初始值。然后我创建一个遍历向量的第一个nmask元素的for循环,并为每个元素分配向量中平均26个其他元素(由4D int数组voxt定义,其中包含向量地址)。

我的问题是,当我在嵌套循环(第一个cout)中检查向量(phi)中的非零元素的值时,值很好,而且我期望的是。但是,当循环完成遍历所有nmask元素(for (int i= 0; i<nmask; i++)退出)时,我再次检查phi的非零元素,并且它们全部丢失(重置为0),除了最后一个非零元素(和元素)手动设置为1的tvox。

我觉得因为phi是在所有循环之外初始化的,所以不应该重置值,并且嵌套循环中的任何更新元素应该在循环退出时保持更新。关于发生了什么/如何解决这个问题的任何想法?代码如下;我试图从我得到的输出的意义上评论。提前谢谢。

vector<double> phi(nmask+3, 0); //vector with nmask+3 elements all set to 0 (nmask = 13622)
    phi[tvox]= 1; //tvox is predefined address (7666)

    for (int n= 0; n<1; n++)
    {
        vector<double> tempPhi(phi); //copy phi to tempPhi

        for (int i= 0; i<nmask; i++)
        {
            for (int a= -1; a<=1; a++)
            {
                for (int b= -1; b<=1; b++)
                {
                    for (int c= -1; c<=1; c++)
                    {
                        if (!(a==0 && b==0 && c==0))
                        {
                            //oneD26 is just (double) 1/26
                            phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
                            if (phi[i]!=0)
                            {
                                //this gives expected results: 27 nonzero elements (including tvox)
                                cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
                            }
                        }
                    }
                }
            }
        }

        phi[svox]= 0; //svox = 7681
        phi[tvox]= 1;

        for (int q= 0; q<nmask; q++)
        {
            //this gives only 2 nonzero values: phi[tvox] and phi[9642], which was the last nonzero value from 1st cout
            if (phi[q]!=0)
                cout << q << " " << phi[q] << endl;
        }

    }

4 个答案:

答案 0 :(得分:2)

很难说出发生了什么,但最简单的解释是,在phi [i]设置为非零并显示到cout之后,它会在之后的迭代中通过内部循环再次设置为零

答案 1 :(得分:1)

如果你进行一些跟踪并在更新前检查phi[i],你会发现你经常用零覆盖一个非零元素。

注意:我不知道你的代码是做什么的,这是纯粹的Sherlock Holmes推理..如果在循环之后你只找到2个非零元素那么唯一合乎逻辑的结果是在稍后将某些东西更新为非零之后你将它更新为零的循环。

答案 2 :(得分:1)

phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];

使用a,b和c运行的嵌套for循环运行具有相同i值的组合9次迭代。由于每次都将phi [i]覆盖为一个新值,因此只保留上一次迭代的值,其中a和c都是1.如果最后一次迭代恰好产生零值,则phi [i]将有很多零。也许你打算做一些像phi [i] + = ...而不是phi [i] = ...?

答案 3 :(得分:0)

我建议用

之类的东西替换循环的肉
const boost::irange domain(-1,2);
for (int i: boost::irange(0, nmask)) for (int a: domain) for (int b: domain) for (int c: domain)
{
    if (a==0 && b==0 && c==0)
        continue;
    //oneD26 is just (double) 1/26
    phi[i]= tempPhi[i]+oneD26*tempPhi[voxt[i][1+a][1+b][1+c]];
    if (phi[i]!=0)
    {
        //this gives expected results: 27 nonzero elements (including tvox)
        cout << n << " " << i << " " << a << b << c << " " << phi[i] << endl;
    }
}

当然,为简洁起见,我假设boost/range.hpp和c ++ 0x编译器。但是,使用琐碎的宏,你可以实现相同的目标。这是没有编写/使用正确的combinations算法(为什么不在标准中,无论如何)。