如何改写多重循环

假设有类似下面的多重循环:

for(i=0; i<3; i++)
    for (j=2; j<6; j++)
       for (k=5; k<16; k++)
            for (l=3; l<5; l++)
              {
                 //do something with i,j,k,l
              }

像上面一共有4重循环,有时候可能更多,如何将任意多重循环用2重循环来改写呢?

方法1:

    const intupper[4]= {3,6,16,5};
    const int lower[4]= {0,2,5,3};
    int index[4]= {0,2,5,3};
    int level;

    do{
          level=3;
          //do something with index[], such as print
          while(level>=0 && (++index[level]>=upper[level])){
              index[level]=lower[level];
    level--;
   }
    }while (level>=0);

上面的两层循环中,外层的do循环每次都从level=3开始,经过内层循环后检测level是不是还>=0。内层循环会做如下工作:
1) ++index[level]
2) 判断当前的level是不是已经到边界(upper[level]),
 如果已到边界,将index[level]重新置为起始值,并将level减1,也就是到了上面一层;
 否则跳过内层循环。

如果还想不明白,在//do something的地方打印出index[0],index[1], index[2], index[3]即可,它们分别对应前面的i,j,k,l。也可以用下面的方法,原理差不多:

方法2:
do {      
      //do something with index[], such as print

      for (level=3; level>=0; level--) {
             index[level]++;
             if (index[level] >= upper[level])   
                   index[level] = lower[level];
            else 
                   break;
      }    
} while(level >= 0);

方法3:

扫描二维码关注公众号,回复: 153863 查看本文章

说起循环我们就应该想到递归,所以我们也可以用递归来改写这个多重循环,原理跟上面的方法差不多,只是外层循环用递归代替了。代码如下:

void dfs(int arr[], int id) {
    int i;
   //do something with arr[], such as print
    if ((arr[0]==upper[0]-1) && (arr[1]==upper[1]-1) && (arr[2]==upper[2]-1) && (arr[3]==upper[3]-1))
        return;

    for (i=3; i>=0; i--) {
        arr[i]++;
        if (arr[i]>=upper[i])
            arr[i]=lower[i];
        else
            break;
    }
    dfs(arr, i);
}

调用的时候用dfs(index, 3)即可。


 



猜你喜欢

转载自blog.csdn.net/roufoo/article/details/79171826