【问题标题】:Java: Combination of recursive loops which has different FOR loop inside; Output: FOR loops indexesJava:内部具有不同 FOR 循环的递归循环的组合;输出: FOR 循环索引
【发布时间】:2012-06-03 10:14:01
【问题描述】:

目前递归对我来说是新鲜且困难的话题,但是我需要在我的一种算法中使用它。

这是挑战:

我需要一个方法来指定递归次数(嵌套 FOR 循环的次数)和每个 FOR 循环的迭代次数。结果应该告诉我,与计数器类似的东西,但是计数器的每一列都限制为特定的数字。

ArrayList<Integer> specs= new ArrayList<Integer>();
  specs.add(5); //for(int i=0 to 5; i++)
  specs.add(7);
  specs.add(9);
  specs.add(2);
  specs.add(8);
  specs.add(9); 

public void recursion(ArrayList<Integer> specs){
  //number of nested loops will be equal to: specs.size();
  //each item in specs, specifies the For loop max count e.g:
  //First outside loop will be: for(int i=0; i< specs.get(0); i++)
  //Second loop inside will be: for(int i=0; i< specs.get(1); i++)
  //...
}

结果将类似于本手册的输出,嵌套循环:

    int[] i;
    i = new int[7];

    for( i[6]=0; i[6]<5; i[6]++){
        for( i[5]=0; i[5]<7; i[5]++){
            for(i[4] =0; i[4]<9; i[4]++){
                for(i[3] =0; i[3]<2; i[3]++){
                    for(i[2] =0; i[2]<8; i[2]++){
                        for(i[1] =0; i[1]<9; i[1]++){
                            //...
                            System.out.println(i[1]+" "+i[2]+" "+i[3]+" "+i[4]+" "+i[5]+" "+i[6]);
                        }
                    }
                }
            }
        }
    }

我已经杀了 3 天,仍然没有结果,在互联网上搜索它,但是例子太不同了。因此,我有生以来第一次在互联网上发布编程问题。提前谢谢你,你可以随意更改代码效率,我只需要相同的结果。

【问题讨论】:

    标签: java recursion counter nested-loops


    【解决方案1】:
    // ...
       recursion (specs, specs.size () - 1);    
    
    // ...
    
       public void recursion(ArrayList<Integer> specs, int startWith){
    
          for (int i = 0; i < specs.get(startWith); i++) {
             // ...
             if (startWith - 1 >= 0)
                recursion (specs, startWith - 1);
          }
        }
    

    【讨论】:

    • 添加 System.print (specs.get(startWith) + " ");在 for 循环之前。
    • 不会打印不完整的堆积吗?
    • 感谢您的快速回复@JohnB,但是您的代码输出显示不同:请执行手动嵌套循环(我包含在我的帖子中)并查看输出应该是什么样子.
    • 你不能自己做吗?您必须更改递归以从规范的最后一项开始并向后移动。我已经编辑了我的答案。
    【解决方案2】:

    您的函数现在还需要specs 数组的索引以用于迭代,以及应该打印的先前数字:

    public void recursion(ArrayList<Integer> specs, int index, String output) {
        if( index >= specs.size() ) {
             System.out.println(output);
            return;
        }
        for (int i = 0; i < specs.get(index); i++ )
            recursion( specs, index+1, Integer.toString(i) + " " + output );
    }
    

    你应该这样称呼它:

    ArrayList<Integer> specs= new ArrayList<Integer>();
    specs.add(5);
    specs.add(7);
    specs.add(9);
    specs.add(2);
    specs.add(8);
    specs.add(9);
    
    recursion( specs, 0, "" );
    

    【讨论】:

    • 感谢您的快速响应,这正是我所需要的。只是删除了一个小错误:resursion( specs, index+1, Integer.toString(i) + " " + output );
    • @winjj:哦!为错误道歉!我主要是一名 C# 程序员,这就是 C# 语法。对不起,不客气。
    【解决方案3】:

    这个 sn-p 是否给出了你想要的输出? (可编译可执行)

    import java.util.ArrayList;
    import java.util.List;
    
    public class SO {
    
        static ArrayList<Integer> specs = new ArrayList<Integer>();
        static int[] i;
    
        public static void main(String[] args) throws Exception {
            specs.add(5); //for(int i=0 to 5; i++)
            specs.add(7);
            specs.add(9);
            specs.add(2);
            specs.add(8);
            specs.add(9);
            i = new int[specs.size()];
            printMe(0, specs, i);
        }
    
        static void printMe(int depth, List<Integer> _specs, int[] i) {
            if (_specs.isEmpty()) {
                System.out.println(printI(i));
                return;
            } else {
                for (int j = 0; j < _specs.get(0); j++) {
                    i[depth] = j + 1; // + 1 since you seems to want to go from 1 and not 0
                    printMe(depth + 1, _specs.subList(1, _specs.size()), i);
                }
            }
        }
    
        static String printI(int[] i) {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < i.length; j++) {
                sb.append(i[j]);
                if (j < i.length - 1) {
                    sb.append(" ");
                }
    
            }
            return sb.toString();
        }
    }
    

    【讨论】:

    • 我的答案和其他人使用非常相似的递归,有些是从左到右(就像我的代码一样),有些是从右到左(我想说的是更多“传统的”)。你应该看看它们的异同——也许这会帮助你很好地掌握基本的递归。祝你好运。
    • 谢谢大家,您的所有答案都非常有效(JohnB 除外)。还有一个简单的问题:你是怎么做到的,快吗?是编程经验还是你以前做过类似的方法?此外,Stack Overflow 应该考虑实现捐赠功能。比如,你可以得到其他人的奖励。不仅通过文字感谢您和反馈,还为您提供帮助。 (就我个人而言,我只是个穷学生,但我相信有专业人士会很乐意为您捐款)。
    • 结束这个话题:可行,问一下你的哪个答案在性能方面最有效?就我个人而言,对我来说,它们都有效,我很高兴。这个问题的答案可能对其他人有用。再次感谢。
    • @vvinjj 如果您想测量性能,请使用分析器(如果有的话,Netbeans 中有一个)或者您可以使用它:stackoverflow.com/a/238943/1140748(将方法运行到循环中以获得更准确结果)
    【解决方案4】:

    你可以试试这个:

    public static void loops(ArrayList<Integer> specs, int idx, StringBuilder res){
        if(idx==specs.size()-1){
            for (int i = 0; i < specs.get(idx); i++) {
                System.out.println(i+" "+res);
            }
        }
        else{
            for(int i=0;i<specs.get(idx);i++){
                res.insert(0,i+" ");
                loops(specs,idx+1,res);
                res.delete(0, 2);
            }
        }
    }
    

    然后调用:

        ArrayList<Integer> specs= new ArrayList<Integer>();
        specs.add(5); //for(int i=0 to 5; i++)
        specs.add(7);
        specs.add(9);
        specs.add(2);
        specs.add(8);
        specs.add(9);
        loops(specs,0, new StringBuilder());
    

    【讨论】:

      猜你喜欢
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      相关资源
      最近更新 更多