Recursive solution
For me, it looks like a recursive solution. You can replace cloning your path array with stacks to improve performance:
char[] pool = new char[]{'1', '2', '3'}; Stack<int> stack = new Stack<int>(); // Actually, resulting length should be the same length as pool array int length = pool.length; public void buildStringRec(int pos) { if (length == pos + 1) { System.out.println(String.valueOf(root)); return; } for(char c : pool){ stack.Push(c); buildStringRec(pos + 1); stack.Pop(c); } }
Iterative solution
Suppose for some reason you need to do iteratively.
I am sure there is a better solution. However, this is the best I could do.
You can rephrase your task differently:
How to output ALL numbers in the base N of length N.
Suppose you have an array of length 3: {'a', 1, 'z'} .
Your desired answer would be:
aaa aa-1 aaz a-1-a a-1-1 a-1-z aza az-1 azz 1-aa 1-a-1 1-az
Now let's look at the indices of these values:
0-0-0 0-0-1 0-0-2 0-1-0 0-1-1 0-1-2 0-2-0 0-2-1 0-2-2 2-0-0 2-0-1 2-0-2
Actually, the consecutive numbers in the base are 3: 000, 001, 002, 010, 011, 012, 020, 021, 022, 200, 201, 202 .
Keep in mind the formula for calculating them: base ^ length . In our case, length == base . So this is base ^ base .
Now our task becomes simpler:
int[] toBase(long bs, long value) { int[] result = new int[bs]; for (long i = bs - 1; i >= 0; i--) { result[i] = (int)(value % bs); value = value / bs; } return result; } long Pow(long a, long b) { long result = 1; for (int i = 0; i < b; i++) result *= a; return result; } char[] pool = new char[] {'a', 'b', 'c'}; void outputAll() { long n = pool.Length; for (long i = 0; i < Pow(n, n); i++) { int[] indices = toBase(n, i); for (int j = 0; j < n; j++) Console.Write("{0} ", pool[indices[j]]); Console.WriteLine(); } }
Of course, there may be some optimizations:
- No need to count
toBase every time. It is easier and more efficient to initiate from 000 and each time calculate the next number. - You can change the
Pow function to use the fast exponentiation by squaring algorithm, etc.
This is just an example explaining the approach.
Keep in mind that an array of length 3 will only contain 27 such combinations. However, an array of length 7 will have 823543. It grows exponentially.
Working sample
Here is the DotNetFiddle working demo .
Just change the values ββof the pool array to get the results. Here and in all the examples above, I used C #. It can be easily converted to C ++ :)
As for me, it works great for lengths up to 7 (about 1 - 1.5 seconds).
Of course, you will need to remove console output in order to get such results. The console exit is very slow .