【问题标题】:Iterate over m^n combinations with nested loops [closed]使用嵌套循环迭代 m^n 组合[关闭]
【发布时间】:2021-07-24 02:26:18
【问题描述】:

我有一个维度为n 的数组y,每个维度都有m 条目。 如何使用嵌套的 for 循环遍历所有索引组合?

我想获得所有可能的总和组合,如以下代码所示:

for (int i = 0; i < m; ++i) {

    for (int j = 0; j < m; ++j) {
        ...
        for (int k = 0; k < m; ++k) {
            z = x[0] + y[i]*x[1] + y[j]*x[2] + ... + y[k]*x[n];
        }
    }
}

     

如果使用for 循环无法做到这一点,那还能如何实现?

【问题讨论】:

  • 您可以使用大小为 N 个嵌套循环的 std::vector 并在每个循环中更新每个条目。
  • 你可以使用递归。它可以证明是一个更好的替代品
  • @Daniyal Shaikh 感谢您的回复。我有点困惑如何在这种情况下使用递归
  • 如果您向我解释您的确切问题,我可能会有所帮助。谢谢
  • z 不会在循环的每次迭代中被覆盖吗? z 的最终值将是 x[0] + y[m-1][*x[1] + y[m-1]*x[2] + ...

标签: c++ c loops recursion nested


【解决方案1】:

这是问题的解决方案,可能不是最佳解决方案,但说明了这个想法。由于您需要一次使用与 y 一样多的索引来索引 y,因此您需要一个数组。数组的索引将在每次迭代中递增,从第 0 个索引开始。当第 0 个索引达到 m 时,我们继续一个 1,就像正常的加法一样。当下一个索引处的整数达到 m 时,我们将 1 结转到下一个索引。当所有索引从 0 变为 m - 1 时,我们就知道我们已经完成了。 Test it in the browser if you wish.

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::vector<int> y = { 1, 2, 3 };
    std::vector<int> x = { 0, 1, 2, 3 };
    std::vector<int> indices = { 0, 0, 0 };
    int m = y.size();
    int sum = 0;
    
    int index_to_increment_next = 0;
    
    while (index_to_increment_next < m)
    {
        // sum up at current indices
        sum += x[0];
        for (int i = 0; i < m; i++)
        {
            sum += x[i + 1] * y[indices[i]]; 
        }
        
        int j;
        for (j = 0; j < m; j++)
        {
            if (indices[j] < m - 1)
            {
                // increment indices
                indices[j]++;
                break;
            }
            // when the index reaches m, reset it to 0 
            // and try to increment the next one
            indices[j] = 0;
        }
        
        // on the last iteration, this will be equal to m
        // and all of the indices will be reset back to 0
        index_to_increment_next = j;
    }
    
    std::cout << sum;
}

更新

对于每个可能的组合,我需要一个单独的总和 z = x[0] + y[i]*x[1] + y[j]*x[2] + ... + y[k]*x[ n] 其中 i,j,...k 是 n 个计数器,取值从 0 到 m。

只需在每次迭代中保存单独的总和并将它们存储在例如一个向量。 See the code.

// declare above the while
std::vector<int> sums;

// ...

int sum = x[0];
for (int i = 0; i < m; i++)
{
    sum += x[i + 1] * y[indices[i]]; 
}
sums.push_back(sum);

【讨论】:

  • 也许我的问题不够清楚,但我需要为每个可能的组合单独计算一个总和 z = x[0] + y[i]*x[1] + y[j]*x[ 2] + ... + y[k]*x[n] i,j,...k 是 n 个计数器,取值从 0 到 m
  • @Miguel 我已经更新了答案
【解决方案2】:

如果我正确理解你的问题,那么Daniyal Shaikh said above in a comment

您可以改用递归。它可以证明是一个更好的选择

n 个 for 循环的简单实现是: (n_counterz 是全局变量)

int n_counter = 0; // which is the 1,2,3 of your y[i]*x[**1**]
int z = x[0];      // all possible combinations of sums at every iteration

void recursion(int n, int m){
   n_counter++;
   for(int i=0 ; i<m ; i++){
      z += y[i]*x[n_counter];
   }

   if(n_counter<=n){ // go deeper n times, which is equal to n for-loops
      recursion(n, m);
   }

   return;
}

每次我们深入递归时,n_counter 都会增加,因为我们需要增加的数字。

例如数字 2:“.. + y[j]*x[2] + ..”。

最后,您所要做的就是打印 z。

【讨论】:

  • 也许我的问题不够清楚,但我需要为每个可能的组合单独计算一个总和 z = x[0] + y[i]*x[1] + y[j]*x[ 2] + ... + y[k]*x[n] i,j,...k 是 n 个计数器,取值从 0 到 m
  • 您可以在for循环下添加一个大小为m的数组,分别保存每个总和。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多