I found a link online that shows an algorithm to generate all combinations of a string: http://www.mytechinterviews.com/combinations-of-a-string
Algorithm is copied belo
We can generate all the sub strings of a string by using the bit concept which has been mentioned previously. Here is the code (in C++ , but you get the idea) to do that : -
string s;
int n = s.size();
int num = 1<<n;
for(int i =1; i< num ; i++){ //Checks all the permutations.
int value = i;
int j, pos;
for (j=1, pos=1; j < num; j<<=1, pos++) //Finds the bits that are set
if (i & j)
cout<<s[pos-1]; //You can print s[n-pos] to print according to bit position
cout<<endl;
}
Eg;- String s = abc ,
The size is 3 . So we check from 1 to 7 ( 1<<3).
for i = 1 ( 001 ) , the first bit is set, so a is printed.
for i = 2 ( 010 ) , the second bit is set, so b is printed.
for i = 3 ( 011 ) , the first and second bit are set, so ab is printed.
.
.
.
for i = 7 ( 111 ) , all three bits are set, so abc is printed.
It fits very logically. You see what we have here is a recursive algorithm. At each step in position i
we put a letter of the string then call the function recursively to put another letter on the next position. However, when we return from recursion, we need to remove the character we put initially, so that we can replace it with the next possible one in the sequence. Example:
append a on pos 0 -> a
call recursion
append a on pos 1 -> aa
call recursion
append a on pos 2 -> aaa
return from recursion
remove a from pos 2 -> aa
append b on pos 2 -> aab
return from recursion
remove b from pos 2 -> aa
append c on pos 2 -> aac
etc.
outstr.deleteCharAt(outstr.length() - 1);
means that you have
n^(n-1)/2 pairs of combinations.
The iterative for-loop doesn't stop after the recursive function call so you need to delete the last char in the output buffer because you don't want to get
n^n/2 pairs of combinations.
In a graph theory it would be a short circuit.
Here is C++ code without the tricky backtracking step in OP's question.
#include <iostream>
#include <string>
using namespace std;
static const string in("abc");
void combine(int i, string out)
{
if (i==in.size()) {
cout << out << endl;
return;
}
combine(i+1, out);
combine(i+1, out+in[i]);
}
int main()
{
combine(0, "");
return 0;
}
I hope this better captures the spirit of combinations.