print combinations of strings in a jagged array

六月ゝ 毕业季﹏ 提交于 2019-12-24 08:58:59

问题


Say I have an array of strings that look like:

{{"blue", "red"}, {"1", "2", 3"}, {"dog","cat", "fish", "bird"}}

I want to print the combinations of the arrays:

blue 1 dog
blue 1 cat
...
...
red 3 bird

However I want the jagged array to have rows and column that are user specified. How can I create a similar approach but in a dynamic and iterative way? Also I'm working with arrays and not ArrayList because as a beginner I want to see what I can do with arrays before learning ArrayList. My code is below:

Scanner input = new Scanner(System.in);
System.out.print("Enter number of arrays: "); 
int arrays = input.nextInt();
String [][] array = new String[arrays][]; 

for(int i = 0; i < x; i++){
   System.out.print("Enter number of elements for array: ");
   int elements = input.nextInt();
   input.nextLine();
   arrays[i] = new String[elements]; 

   for(int j = 0; j < elements ; j++){ 
      System.out.print("Enter string: ");
      String word = input.nextLine();
      arrays[i][j] = word;
   }
}     

回答1:


This answer will print all combinations, without use of recursion, but will fail if the total number of combinations exceeds Long.MAX_VALUE. Since printing that many lines would never end anyway, that's not really a problem.

To print combinations in order, think of an incrementing number, where each digit of the number is an index into the corresponding sub-list.

Examples (using list of list from question):

000: blue 1 dog
001: blue 1 cat
002: blue 1 fish
003: blue 1 bird
010: blue 2 dog
...
121: red 3 cat
122: red 3 fish
123: red 3 bird

Each "digit" will roll over when it reaches end of corresponding sublist, e.g. last sublist only has 4 elements, so digit rolls over from 3 to 0.

Note: A "digit" can count higher than 9. Think hex for one way to represent that.

Now, the number of digits is dynamic too, i.e. the size of the outer list. One way to do this with simple loops, is to calculate the total number of combinations (2 * 3 * 4 = 24), then calculate the digits using division and remainder.

Example:

Combination #10 (first combination is #0):
  10 % 4                 = 2 (last digit)
  10 / 4 % 3     = 2 % 3 = 2 (middle digit)
  10 / 4 / 3 % 2 = 0 % 2 = 0 (first digit)
  Digits: 022 = blue 3 fish

To help with this, we first build an array of divisors, e.g. div[] = { 12, 4, 1 }, and find the total number of combinations (24).

long[] div = new long[array.length];
long total = 1;
for (int i = array.length - 1; i >= 0; i--) {
    div[i] = total;
    if ((total *= array[i].length) <= 0)
        throw new IllegalStateException("Overflow or empty sublist");
}

Now we can loop through the combinations and print the result:

for (long combo = 0; combo < total; combo++) {
    for (int i = 0; i < array.length; i++) {
        int digit = (int) (combo / div[i] % array[i].length);
        if (i != 0)
            System.out.print(' ');
        System.out.print(array[i][digit]);
    }
    System.out.println();
}

With input from question:

String[][] array = {{"blue", "red"}, {"1", "2", "3"}, {"dog","cat", "fish", "bird"}};

We get the following output:

blue 1 dog
blue 1 cat
blue 1 fish
blue 1 bird
blue 2 dog
blue 2 cat
blue 2 fish
blue 2 bird
blue 3 dog
blue 3 cat
blue 3 fish
blue 3 bird
red 1 dog
red 1 cat
red 1 fish
red 1 bird
red 2 dog
red 2 cat
red 2 fish
red 2 bird
red 3 dog
red 3 cat
red 3 fish
red 3 bird

It can handle any combination of sub-arrays, e.g. with 4 sub-arrays of sizes 2, 3, 2, and 2:

String[][] array = {{"small", "large"}, {"black", "tan", "silver"}, {"lazy", "happy"}, {"dog", "cat"}};
small black lazy dog
small black lazy cat
small black happy dog
small black happy cat
small tan lazy dog
small tan lazy cat
small tan happy dog
small tan happy cat
small silver lazy dog
small silver lazy cat
small silver happy dog
small silver happy cat
large black lazy dog
large black lazy cat
large black happy dog
large black happy cat
large tan lazy dog
large tan lazy cat
large tan happy dog
large tan happy cat
large silver lazy dog
large silver lazy cat
large silver happy dog
large silver happy cat



回答2:


Here's another approach that uses an array of integer indices to simulate a variable number of nested for loops:

    Scanner input = new Scanner(System.in);
    System.out.print("Enter number of arrays: ");
    int arrays = input.nextInt();
    String[][] array = new String[arrays][];

    for (int i = 0; i < arrays; i++) {
        System.out.print("Enter number of elements for array #" + i + ": ");
        int elements = input.nextInt();
        input.nextLine();
        array[i] = new String[elements];

        for (int j = 0; j < elements; j++) {
            System.out.print("Enter string: ");
            String word = input.nextLine();
            array[i][j] = word;
        }
    }

    int[] indices = new int[array.length];
    while (indices[0] < array[0].length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < indices.length; ++i) {
            if (i > 0) {
                sb.append(' ');
            }
            sb.append(array[i][indices[i]]);
        }
        System.out.println(sb.toString());
        for (int i = indices.length - 1; i >= 0; --i) {
            if (++indices[i] < array[i].length) {
                break;
            }
            if (i != 0) {
                indices[i] = 0;
            }
        }
    }



回答3:


My idea is the following. Say we have this 2-d array

String[][] strings = {{"blue", "red"},
                      {"1", "2", "3"},
                      {"dog", "cat", "bird", "fish"}};

We can generate permutation inside an array but with some conditions included.

So firstly we find the maximum line length in our table.

int max = 0;
for (int i = 0; i < strings.length; i++) {
    if(max < strings[i].length) {
        max = strings[i].length;
    }
}

Then we just generate the permutations

int[] permutations = new int[strings.length];

void permute(int k) {
    for(int i = 0; i < max; i++) {
        permutations[k] = i;
        if(valid(k)) {
            if(k == strings.length - 1) {
                printSolution();
            } else {
                permute(k + 1);
            }
        }
    }
}

valid function check that number on position i is not higher than then length on the ith line in our table.

boolean valid(int k) {
    for(int i = 0; i < k; i++) {
        if(permutations[i] >= strings[i].length) return false;
    }
    return true;
}

print solution method:

void printSolution() {
    for(int i = 0; i < strings.length; i++) {
        System.out.print(strings[i][permutations[i]] + " ");
    }
    System.out.println();
}

and the result:

blue 1 dog 
blue 1 cat 
blue 1 bird 
blue 1 fish 
blue 2 dog 
blue 2 cat 
blue 2 bird  
blue 2 fish 
blue 3 dog 
blue 3 cat 
blue 3 bird 
blue 3 fish 
red 1 dog 
red 1 cat 
red 1 bird 
red 1 fish 
red 2 dog 
red 2 cat 
red 2 bird 
red 2 fish 
red 3 dog 
red 3 cat 
red 3 bird 
red 3 fish 


来源:https://stackoverflow.com/questions/46374381/print-combinations-of-strings-in-a-jagged-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!