【问题标题】:Dynamically change the number of nested for loops动态改变嵌套for循环的数量
【发布时间】:2023-03-15 12:55:01
【问题描述】:

我不知道这是不是一个愚蠢的问题,但我需要在不使用递归的情况下动态更改 for 循环的数量。

例如,如果 n=3,我需要 3 个嵌套的 for 循环。

for(int i=0; i<size; i++){
   for(int j=0; j<size-1; j++){
       for(int k=0; k<size-2; k++){
          //do something
       }
   }
}

如果 n=5:

for(int i=0; i<size; i++){
   for(int j=0; j<size-1; j++){
       for(int k=0; k<size-2; k++){
          for(int l=0; l<size-3; l++){
              for(int m=0; m<size-4; m++){
                  //do something
              }
          }
       }
   }
}

有没有办法在不递归的情况下实现这一点? 另一个问题:Java 中的 Multiple Dispatch 有什么用?我正在尝试用一种方法编写一些东西,它应该在参数的不同情况下运行不同的事件。 NO IF 语句/三元运算符/案例。

注意:我只能有一种方法(部分问题),并且不能使用递归。对不起。

【问题讨论】:

  • 输入和输出到底是什么?恐怕答案可能取决于他们。
  • n 是否有最大可能值?
  • n 没有最大值。 1 到正信息。
  • 在计算机上不可能是正无穷大。可以是Integer.MAX_VALUELong.MAX_VALUE。有一种方法可以让它变大,但 Long.MAX_VALUE 足够大,以至于循环 0...Long.MAX_VALUE 可能需要数年时间才能完成。
  • 如果你解释了整个问题呢?或许您正专注于解决基本问题的错误方法。

标签: java dynamic


【解决方案1】:

想想你经历了多少次这个循环。好像是(size!) / (size - n)!:

int numLoops = 1;
for (int i = 0; i < n; i++) {
    numLoops*= (size - i);
}

for (int i = 0; i < numLoops; i++) {
    //do something
}

【讨论】:

    【解决方案2】:

    这取决于您到底想做什么。递归总是可以用迭代代替(参见this post 使用Stack 存储状态的示例)。

    但也许模 (%) 运算符可以在这里工作?即有一个递增变量(i)的循环,然后使用模数(i % 3 等)计算其他变量。如果有不同数量的变量,您可以使用 Map 间接存储变量的值。

    【讨论】:

    • 当然,是的,这是众所周知的事实。所以更好。如果嵌套层数太多,他可以使用我的想法并用 Stack 替换递归。我怀疑模数会有所帮助。我认为他只想编写 N 个嵌套循环,但 N 是一个变量。
    【解决方案3】:

    您必须创建循环计数器数组并手动递增。

    快速而肮脏的例子:

    public static void nestedFors(int n, int size) {
      assert n > size;
      assert size > 0;
    
      int[] i = new int[n];
      int l = n - 1;
      while(l >= 0) {
        if(l == n - 1) {
          System.out.println(Arrays.toString(i));
        }
        i[l]++;
        if(i[l] == size - l) {
          i[l] = 0;
          l--;
        } else if(l < n - 1) {
          l++;
        }
      }
    }
    

    用您自己的代码替换System.out.println(Arrays.toString(i))

    您可以在这里查看:http://ideone.com/IKbDUV

    【讨论】:

    • 如果 OP 想用 n 计数器做某事,我看不出有办法做这样的事情。
    【解决方案4】:

    这有点令人费解,但是:这是一种无需递归、在一个函数中且无需 ifs 的方法。

    public static void no_ifs_no_recursion(int n){  
        int[] helper = new int[n-1];
        int[] pointers = new int[n]; //helper for printing the results
    
        int totalsize = 1;
        for (int loops = 2; loops <= n; loops++){
            helper[n - loops] = totalsize;
            totalsize*=loops;
        }
        for (int i=0; i<totalsize; i++){
            int carry = i;
            for (int loops = 0; loops < n-1; loops++){
                pointers[loops] = carry/helper[loops];
                carry = carry - (pointers[loops]*helper[loops]);
            }
    
            System.out.println(Arrays.toString(pointers));
            //or do something else with `i` -> `pointers[0]`, `j` -> `pointers[1]`, `k` -> `pointers[2]` etc..
        }
    }
    

    【讨论】:

      【解决方案5】:

      我认为你需要一个回溯算法。 但是你会用递归替换你的嵌套循环。

      我不想在这里发布链接,因为版主似乎不喜欢这样。

      看看“八皇后之谜”(你可以谷歌一下),你就会明白我的想法。

      我知道这个想法是可行的,因为我曾多次向自己提出过同样的问题(你有过),并且我已经成功应用了几次。

      这里是一个小例子(我改变了它,因为前一个有点复杂)。

      public class Test001 {
      
      public static void main(String[] args) {
          loop(0, 5, 10);
      }
      
      /**
       * max_level - the max count of nesting loops
       * size - the size of the collection
       * 
       * 0 - top most level
       * level 1 - nested into 0
       * level 2 - nested into 1
       * ... 
       * and so on.
       */
      private static void loop(int level, int max_level, int size){
          if (level > max_level) return;
      
          for (int i=0; i<size-level; i++){
              System.out.println("Now at level: " + level + " counter = " + i);
              loop(level + 1, max_level, size);
          }
      }
      
      }
      

      但这仍然使用递归。


      【讨论】:

      • 不,他们不(不喜欢那样);)。引用参考文献很好。不过,它不应该只是一个链接的答案。
      猜你喜欢
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      相关资源
      最近更新 更多