仅在“特定”索引上迭代嵌套的“for”循环。 C ++

时间:2021-03-03 14:31:27

I have 4 nested "for" loops.

我有4个嵌套的“for”循环。

     for(int i=0; i<len1; i++) {
      for(int j=0; j<len2; j++) {
       for(int k=0; k<len1; k++) {
        for(int l=0; l<len2; l++) {
          //perform some calculations/operations.
        }
       }
      }
     }

The thing is, this whole code will run over each and every index of every "for" loop from 0 to len1/len2. I don't want it to do that. Instead, I want these loops to iterate over certain "specific" indices and skip the rest(by skipping I mean TOTAL skipping, it should not iterate over the unwanted indices).

问题是,整个代码将遍历从0到len1 / len2的每个“for”循环的每个索引。我不希望它这样做。相反,我希望这些循环迭代某些“特定”索引并跳过其余的(通过跳过我的意思是TOTAL跳过,它不应该迭代不需要的索引)。

To give a more elaborate explanation, here is how the iterations will happen when the above code snippet is run.

为了给出更详细的解释,下面是在运行上面的代码片段时如何进行迭代。

i    j    k    l
0    0    0    0
0    0    0    1
0    0    0    2
0    0    0    3
.    .    .    .
.    .    .    .
.    .    .    .
len1 len2 len1 len2

But what I want is the following...

但我想要的是以下......

0    0    0    63
0    0    0    450
0    0    0    569
0    0    3    87
0    0    78   999
.    .    .    .
.    .    .    .
.    .    .    .
29   65   99   357
29   66   21   222
.    .    .    .

and so on... Firstly is it possible with nested "for" loops?

等等......首先,嵌套的“for”循环是否可行?

Secondly and most importantly I want to do it only with nested "for" loops. No other method.

其次,最重要的是我只想用嵌套的“for”循环来做。没有其他方法。

Thirdly the iterations over the "specific" indices I want is NOT random.

第三,我想要的“特定”指数的迭代不是随机的。

3 个解决方案

#1


0  

If you can define the starting point for an inner loop in terms of the outer loops, sure. Example:

如果您可以根据外部循环定义内部循环的起点,请确保。例:

for(int i=0; i<len1; i++) {
  for(int j=0; j<len2; j++) {
   for(int k=0; k<len1; k++) {
    int lStart = DetermineBasedOn(i, j, k);
    for(int l=lStart; l<len2; l++) {
      //perform some calculations/operations.
    }
   }
  }
 }

Note that

DetermineBasedOn(i, j, k);

does not have to be an actual method call. You could set the start index within the body of your loop.

不必是实际的方法调用。您可以在循环体内设置起始索引。

If you need gaps in the region that you iterate, do as suggested by @SamIAm in the comments: Provide a function to determine the next index (though possibly based on multiple variables:

如果您需要在迭代的区域中留下空白,请按照@SamIAm在注释中的建议进行操作:提供一个函数来确定下一个索引(尽管可能基于多个变量:

for(int l=lStart; l<len2; l = GetNextIndex(l, i, j, k)) {

You can use the same technique to end an inner loop earlier (setting e.g. lEnd and using that in place of len2).

您可以使用相同的技术更早地结束内部循环(设置例如lEnd并使用它代替len2)。

Secondly and most importantly I want to do it only with nested "for" loops. No other method.

其次,最重要的是我只想用嵌套的“for”循环来做。没有其他方法。

do and while loops are functionally equivalent to for loops, and may (or may not) be clearer and easier to read in this case. I'm not sure why the bias against other loop constructs, but you can certainly accomplish the same result with a for as with do or while.

do和while循环在功能上等同于for循环,并且在这种情况下可能(或可能不)更清晰,更容易阅读。我不确定为什么偏向其他循环结构,但你肯定可以用do或while来实现相同的结果。

#2


0  

Put your specific indices into a std::vector, and loop over that to get your real indices. With C++ 11, you can use the following syntax to initialize the vector.

将您的特定索引放入std :: vector中,并循环遍历它以获得您的真实索引。使用C ++ 11,您可以使用以下语法初始化向量。

std::vector myFavoriteIndices = {5,7, 11, 8}

for(int i = 0; i < len1; i++) {
    for(int j = 0; j < len2; j++) {
        for(int k = 0; k < len1; k++) {
            for(int l = 0; l < myFavoriteIndices.size(); l++) {
                int trueIndex = myFavoriteIndices[l];
                // do something with trueIndex
            }
        }
    }
}

#3


0  

If I'm understanding correctly , you want certain indexes (you have a method of determining that ? ) to be iterated.

如果我理解正确,你想要迭代某些索引(你有一个确定的方法吗?)。

If you can predetermine the desired indexes then you can use a vector of indices.

如果可以预先确定所需的索引,则可以使用索引向量。

Something like :

就像是 :

 vector<int> iIdx;
 vector<int> jIdx;
 vector<int> kIdx;
 vector<int> lIdx;

 // your inside algorithm section which determines what indexes are needed for each 
 ...
 lIdx.push_back(63);
 ...

 // the new loop
 for (int i=0;i<iIdx.size();i++)
  for (int j=0;j<jIdx.size();j++)
    for (int k=0;k<kIdx.size();k++)
      for (int l=0;l<lIdx.size();l++)
        {
            ii = iIdx[i];
            jj = jIdx[j]; 
            kk = kIdx[k]; 
            ll = lIdx[l];
            // use ii , jj ,kk and ll as you would use i,j,k,l on your original question
        }

This works if you have a way to determine these indexes before the quad loop starts.

如果您有方法在quad循环开始之前确定这些索引,则此方法有效。

Otherwise, you can trim down some loops by this approach at the point where you can generate indexes (for example if you need to know i and j to generate the indexes of k and l, then only kIdx and lIdx will use the above method).

否则,你可以通过这种方法在你可以生成索引的位置减少一些循环(例如,如果你需要知道i和j来生成k和l的索引,那么只有kIdx和lIdx将使用上面的方法) 。

EDIT :

Noted in other comment that you use CUDA.

在其他评论中注明您使用CUDA。

You can compute the iIdx, jIdx, kIdx and lIdx arrays on the CPU and make the for loops on the GPU.

您可以在CPU上计算iIdx,jIdx,kIdx和lIdx阵列,并在GPU上进行for循环。

#1


0  

If you can define the starting point for an inner loop in terms of the outer loops, sure. Example:

如果您可以根据外部循环定义内部循环的起点,请确保。例:

for(int i=0; i<len1; i++) {
  for(int j=0; j<len2; j++) {
   for(int k=0; k<len1; k++) {
    int lStart = DetermineBasedOn(i, j, k);
    for(int l=lStart; l<len2; l++) {
      //perform some calculations/operations.
    }
   }
  }
 }

Note that

DetermineBasedOn(i, j, k);

does not have to be an actual method call. You could set the start index within the body of your loop.

不必是实际的方法调用。您可以在循环体内设置起始索引。

If you need gaps in the region that you iterate, do as suggested by @SamIAm in the comments: Provide a function to determine the next index (though possibly based on multiple variables:

如果您需要在迭代的区域中留下空白,请按照@SamIAm在注释中的建议进行操作:提供一个函数来确定下一个索引(尽管可能基于多个变量:

for(int l=lStart; l<len2; l = GetNextIndex(l, i, j, k)) {

You can use the same technique to end an inner loop earlier (setting e.g. lEnd and using that in place of len2).

您可以使用相同的技术更早地结束内部循环(设置例如lEnd并使用它代替len2)。

Secondly and most importantly I want to do it only with nested "for" loops. No other method.

其次,最重要的是我只想用嵌套的“for”循环来做。没有其他方法。

do and while loops are functionally equivalent to for loops, and may (or may not) be clearer and easier to read in this case. I'm not sure why the bias against other loop constructs, but you can certainly accomplish the same result with a for as with do or while.

do和while循环在功能上等同于for循环,并且在这种情况下可能(或可能不)更清晰,更容易阅读。我不确定为什么偏向其他循环结构,但你肯定可以用do或while来实现相同的结果。

#2


0  

Put your specific indices into a std::vector, and loop over that to get your real indices. With C++ 11, you can use the following syntax to initialize the vector.

将您的特定索引放入std :: vector中,并循环遍历它以获得您的真实索引。使用C ++ 11,您可以使用以下语法初始化向量。

std::vector myFavoriteIndices = {5,7, 11, 8}

for(int i = 0; i < len1; i++) {
    for(int j = 0; j < len2; j++) {
        for(int k = 0; k < len1; k++) {
            for(int l = 0; l < myFavoriteIndices.size(); l++) {
                int trueIndex = myFavoriteIndices[l];
                // do something with trueIndex
            }
        }
    }
}

#3


0  

If I'm understanding correctly , you want certain indexes (you have a method of determining that ? ) to be iterated.

如果我理解正确,你想要迭代某些索引(你有一个确定的方法吗?)。

If you can predetermine the desired indexes then you can use a vector of indices.

如果可以预先确定所需的索引,则可以使用索引向量。

Something like :

就像是 :

 vector<int> iIdx;
 vector<int> jIdx;
 vector<int> kIdx;
 vector<int> lIdx;

 // your inside algorithm section which determines what indexes are needed for each 
 ...
 lIdx.push_back(63);
 ...

 // the new loop
 for (int i=0;i<iIdx.size();i++)
  for (int j=0;j<jIdx.size();j++)
    for (int k=0;k<kIdx.size();k++)
      for (int l=0;l<lIdx.size();l++)
        {
            ii = iIdx[i];
            jj = jIdx[j]; 
            kk = kIdx[k]; 
            ll = lIdx[l];
            // use ii , jj ,kk and ll as you would use i,j,k,l on your original question
        }

This works if you have a way to determine these indexes before the quad loop starts.

如果您有方法在quad循环开始之前确定这些索引,则此方法有效。

Otherwise, you can trim down some loops by this approach at the point where you can generate indexes (for example if you need to know i and j to generate the indexes of k and l, then only kIdx and lIdx will use the above method).

否则,你可以通过这种方法在你可以生成索引的位置减少一些循环(例如,如果你需要知道i和j来生成k和l的索引,那么只有kIdx和lIdx将使用上面的方法) 。

EDIT :

Noted in other comment that you use CUDA.

在其他评论中注明您使用CUDA。

You can compute the iIdx, jIdx, kIdx and lIdx arrays on the CPU and make the for loops on the GPU.

您可以在CPU上计算iIdx,jIdx,kIdx和lIdx阵列,并在GPU上进行for循环。