简体   繁体   中英

all possible ways in which K items can be arranged in N slots

I am looking for an algorithm to find all combinations of K values to n items.

Example:

K values are [R,B] & N is 2 so i get {RR, RB, BR, BB} 2*2 = 4 ways

K values are [R,B] & N is 3 so i get {RRR, RRB, RBB, RBR, BRR, BRB, BBR, BBB} 2*2*2 = 8 ways

I need to find out the generic algorithm to find all possible ways in which K items can be arranged in N slots. (repeat is allowed)

Another example would be:

K values are [R,G,B] & N is 5 so i need to find 3^5 = 81 combinations.

This problem lends itself exceptionally well to a recursive solution.

The solution in the general case is clearly formed by taking the solution for N - 1 , and then prepending each of your set's elements in turn to the results. In pseudocode:

f(options, 0) = []
f(options, n) = options foreach o => o ++ f(options, n-1)

This could be implemented recursively in Java, but you'd run into stack overflow errors for moderately large values of n ; and I also suspect the JIT compiler is less effective at optimising recursive algorithms so performance would suffer.

However, recursive algorithms can always be converted into a loop equivalent. In this case it might look something like:

List<String> results = new ArrayList<String>();
results.add(""); // Seed it for the base case n=0
for (int i = 0; i < n; i ++) {
    List<String> previousResults = results;
    results = new ArrayList<String>();
    for (String s : options) {
       for (String base : previousResults) {
           results.add(s + base);
       }
    }
}
return results;

This works (I hope!) similarly to the recursive method - at each iteration it "saves" the current progress (ie the result for n-1 ) to previousResults , then just iterates over the options in turn, to get the result of prepending them to the previous results.

It would be interesting to see the effects of passing the recursive solution through any automatic recursion-to-iterative algorithms, and compare both the readability and performance to this hand-created one. This is left as an exercise for the reader.

I'll using counter of N bit in base keg: k=3, n=5

(0,0,0,0,0)
(0,0,0,0,1),
....
(2,2,2,2,2)

Implementing such a counter is easy, just keep array of size n+1, set all elements tozero at first, each time increase latest element, and if it will exceed from k-1, increase next neighbors (till neighbors are exceeding k-1). action terminates when n+1 element sets to 1.

If you tried and couldn't do so, tell it with comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM