Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recursion instead of multi-loops

I want this method to work for any given number of arguments, i can do that with code generation(with a lot of ugly code), can it be done with recursion? if so how? I understand recursion, but i dont know how to write this.

private static void allCombinations(List<String>... lists) {
    if (lists.length == 3) {
        for (String s3 : lists[0]) {
            for (String s1 : lists[1]) {
                for (String s2 : lists[2]) {
                    System.out.println(s1 + "-" + s2 + "-" + s3);
                }
            }
        }
    }
    if (lists.length == 2) {
        for (String s3 : lists[0]) {
            for (String s1 : lists[1]) {
                    System.out.println(s1 + "-" + s3);
            }
        }
    }
}

2 Answers

Here is a simple recursive implementation:

private static void allCombinations(List<String>... lists) {
  allCombinations(lists, 0, "");
}

private static void allCombinations(List<String>[] lists, int index, String pre) {
  for (String s : lists[index]) {
    if (index < lists.length - 1) {
      allCombinations(lists, index + 1, pre + s + "-");
    }else{
      System.out.println(pre + s);
    }
  }
}
like image 114
Rasmus Faber Avatar answered Jun 03 '26 16:06

Rasmus Faber


Do you particularly need it to be recursive? I'd make it non-recursive but still not special case things:

public static void allCombinations(List<String>... lists) {
    int[] indexes = new int[lists.length];

    while (incrementIndexes(lists, indexes)) {
        StringBuilder builder = new StringBuilder();
        for (int i=0; i < indexes.length; i++) {
            if (i != 0) {
                builder.append("-");
            }
            builder.append(lists[i].get(indexes[i]));
        }
        System.out.println(builder);
    }
}

private static boolean incrementIndexes(List<String>[] lists, int[] indexes) {
    for (int depth = indexes.length-1; depth >= 0; depth--) {
        indexes[depth]++;
        if (indexes[depth] != lists[depth].size()) {
            return true;
        }
        // Overflowed this index. Reset to 0 and backtrack
        indexes[depth] = 0;
    }
    // Everything is back to 0. Finished!
    return false;
}
like image 30
Jon Skeet Avatar answered Jun 03 '26 16:06

Jon Skeet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!