c++向量未在嵌套for循环中更新

c++ vector not updating in nested for loop

本文关键字:循环 更新 for 嵌套 向量 c++      更新时间:2023-10-16

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

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

我觉得由于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;
        }
    }

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

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

注意:我不知道你的代码是干什么的,这纯粹是福尔摩斯的推理。。如果在循环之后你只找到2个非零元素,那么唯一的逻辑结果是在循环中稍后将某个元素更新为非零之后,你将其更新为零。

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

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

我确实建议用之类的东西来替换循环的肉

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算法的情况下(为什么这不在标准中,无论如何)。