0

currently recursion is fresh & difficult topic for me, however I need to use it in one of my algorithms.

Here is the challenge:

I need a method where I specify number of recursions (number of nested FOR loops) and number of iterations for each FOR loop. The result should show me, something simmilar to counter, however each column of counter is limited to specific number.

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++)
  //...
}

The the results will be similar to outputs of this manual, nested loop:

    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]);
                        }
                    }
                }
            }
        }
    }

I already, killed 3 days on this, and still no results, was searching it in internet, however the examples are too different. Therefore, posting the programming question in internet first time in my life. Thank you in advance, you are free to change the code efficiency, I just need the same results.

vvinjj
  • 83
  • 2
  • 9

4 Answers4

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);
      }
    }
JohnB
  • 13,315
  • 4
  • 38
  • 65
  • Add System.print (specs.get(startWith) + " "); before the for loop. – JohnB Jun 03 '12 at 10:24
  • Wouldn't that print incomplete buildups? – esej Jun 03 '12 at 10:44
  • Thank you for fast reply @JohnB , however the output of your code is showing different: please, execute the manual, nested loop (which I included to my post) and see how the output should look like. – vvinjj Jun 03 '12 at 10:45
  • Can't you do that yourself? You must change the recursion to start with the last item of the specs and move backwards. I've edited my answer. – JohnB Jun 03 '12 at 10:50
1

Your function also need to now the index of the specs array to use for iteration, and also the previous numbers that should be printed:

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 );
}

The you should call it like this:

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, "" );
Mohammad Dehghan
  • 17,853
  • 3
  • 55
  • 72
  • thank you for amazingly fast response, this is exactly what I need. Just a minor small mistake was removed: resursion( specs, index+1, Integer.toString(i) + " " + output ); – vvinjj Jun 03 '12 at 10:53
  • @winjj: Oh! Sorry for the mistake! I am mainly a C# programmer, and that was the C# syntax. Sorry, and you're welcome. – Mohammad Dehghan Jun 03 '12 at 11:01
0

Does this snippet give the output you want? (It is compileable and executeable)

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();
    }
}
esej
  • 3,059
  • 1
  • 18
  • 22
  • My answer and the others use very similar recursions, some make the list from left-to-right (as my code does), some from right-to-left (which I'd say is more "traditional"). You should look at the differences and similarities - maybe that will help you getting a good grip on basic recursions. Good Luck. – esej Jun 03 '12 at 11:16
  • Thank you all guys, all your answers perfectly work (except JohnB). And just another quick question: how you do it so, fast? Is it programming experience or you have already done similar methods before? Also, Stack Overflow, should consider implementation of donation function. Such people as, you could be rewarded by other people. Not just by word thank you & feedback, but also to donate for you help. (Personally, I am just poor student, however I am sure there is professionals who will be happy to donate for your help). – vvinjj Jun 03 '12 at 11:43
  • To close this topic: it is feasible, to ask which one of your answers are most efficient in terms of performance? Personally, for me all of them works and I am happy. The answer on this question might be useful for other people. Thanks again. – vvinjj Jun 03 '12 at 11:44
  • @vvinjj If you want to measure performance use a profiler (there is one in Netbeans if you have it) or you can use that : http://stackoverflow.com/a/238943/1140748 (run the method into a loop to have more accurate results) – alain.janinm Jun 03 '12 at 12:26
0

You can try this :

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);
        }
    }
}

And call with :

    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());
alain.janinm
  • 19,951
  • 10
  • 65
  • 112