【问题标题】:c++ vector not updating in nested for loopc ++向量未在嵌套for循环中更新
【发布时间】:2011-09-26 08:34:28
【问题描述】:

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

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

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

    }

【问题讨论】:

  • ....哇,这棵圣诞树很有趣
  • muximam 圈复杂度。
  • 算了,改写代码就不会嵌套那么深了。

标签: c++ vector for-loop nested


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    注意:我不知道你的代码做了什么,这纯粹是福尔摩斯推理。如果在循环之后你只发现 2 个非零元素,那么唯一合乎逻辑的结果是稍后将某些内容更新为非零之后您将其更新为零的循环。

    【讨论】:

      【解决方案3】:
      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] = ...?

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 2021-11-29
          • 1970-01-01
          • 2020-01-29
          • 2013-03-03
          • 2021-07-29
          • 1970-01-01
          • 2019-07-22
          • 1970-01-01
          相关资源
          最近更新 更多