Print all combinations

Question:

Input String 1 = {1, 2, 3, ... , 26}

Input String 2 = {A, B, C, ... , Z}

Output Result 1 = {1, A, 2, B, 3, C, ... , 26, Z}

Output Result 2 = {1, A, 2, A, B, 3, A, B, C, ... , 26, A, B, C, . , Z}


Solution:

public class Combinations {

private static String stringNumbers[];                  //1, 2, 3, ... , 26
private static String stringAlphabets[];                //A, B, C, ... , Z

private static String resultNumberAlphabet[];           //1, A, 2, B, 3, C, ... , 26, Z
private static String resultNumberAlphabets[];          //1, A, 2, A, B, 3, A, B, C, ... , 26, A, B, ... , Z

private static final int MAX_NUMBERS = 26;
private static final int MAX_ALPHABETS = 26;

public static void main(String[] args) {
initVariables();
findCombinations();
printResults(resultNumberAlphabet);
printResults(resultNumberAlphabets);
}

private static void initVariables() {
stringNumbers = new String[MAX_NUMBERS];
stringAlphabets = new String[MAX_ALPHABETS];
resultNumberAlphabet = new String[stringNumbers.length + stringAlphabets.length];
resultNumberAlphabets = new String[stringNumbers.length + (stringAlphabets.length * (stringAlphabets.length + 1)/2)];   //  Summation Equation = [n*(n+1)/2];

for (int i = 0; i < 26; i++) {
stringNumbers[i] = (i + 1) + "";
stringAlphabets[i] = Character.toString((char)(i + 65));
}
}

private static void findCombinations() {
int k = -1;
int l = -1;
for (int i = 0; i < stringNumbers.length; i++) {
resultNumberAlphabet[++k] = stringNumbers[i];
resultNumberAlphabet[++k] = stringAlphabets[i];
resultNumberAlphabets[++l] = stringNumbers[i];
for (int j = 0; j <= i; j++) {
resultNumberAlphabets[++l] = stringAlphabets[j];
}
}
}

private static void printResults(String result[]) {
for (int i = 0; i < result.length; i++) {
System.out.print(result[i]);
if ((i + 1) == result.length) {
System.out.println(".");
} else {
System.out.print(", ");
}
}
}

}


• Why a string array . Just a String would suffice.
• Do we really need to store it in arrays. The computed arrays would only be usde to display. So we can work towards a display method instead of storing and displaying them.

int i;
for(i=1;i<26;i++){
System.out.print(i+", ");
System.out.print(Character.toString((char)(64+i))+", ");
}
System.out.print(i+", ");
System.out.println(Character.toString((char)(64+i))+".");

StringBuilder next = new StringBuilder();
for(i=1;i<26;i++){
System.out.print(i+", ");
next.append(Character.toString((char)(64+i)) + ", ");
System.out.print(next);
}
System.out.print(i+", ");
next.append(Character.toString((char)(64+i)));
System.out.println(next);
// Time complexity: O(n)
// Space complexity: O(n+m*(m+1)/2))

• Assuming we are striving to have a generic implementation wherein we have two input arrays and we wish to provide the output. Even in that case we can carry forward with above implementation with slight changes.

• Having the last condition check seems an unneeded overhead. Instead we loop in for last-but-one index and print the last outside.

if ((i + 1) == result.length)


If you are only using single characters you should use char[] instead of String[] for much better performance.

You should also consider instantiating your class, rather than using statics. So as a first step you would get:

public class Combinations {

private char stringNumbers[];                  //1, 2, 3, ... , 26
private char stringAlphabets[];                //A, B, C, ... , Z

private char resultNumberAlphabet[];           //1, A, 2, B, 3, C, ... , 26, Z
private char resultNumberAlphabets[];          //1, A, 2, A, B, 3, A, B, C, ... , 26, A, B, ... , Z

private final int MAX_NUMBERS = 26;
private final int MAX_ALPHABETS = 26;

public static void main(String[] args) {
Combinations myCombinations = new Combinations();
myCombinations.go();
}

public void go(){
initVariables();
findCombinations();
printResults(resultNumberAlphabet);
printResults(resultNumberAlphabets);
}

private void initVariables() {
stringNumbers = new char[MAX_NUMBERS];
stringAlphabets = new char[MAX_ALPHABETS];
resultNumberAlphabet = new char[stringNumbers.length + stringAlphabets.length];
resultNumberAlphabets = new char[stringNumbers.length + (stringAlphabets.length * (stringAlphabets.length + 1)/2)];   //  Summation Equation = [n*(n+1)/2];

for (int i = 0; i < 26; i++) {
stringNumbers[i] = Character.forDigit(i + 1, 10);
stringAlphabets[i] = (char)(i + 65);
}
}

private void findCombinations() {
int k = -1;
int l = -1;
for (int i = 0; i < stringNumbers.length; i++) {
resultNumberAlphabet[++k] = stringNumbers[i];
resultNumberAlphabet[++k] = stringAlphabets[i];
resultNumberAlphabets[++l] = stringNumbers[i];
for (int j = 0; j <= i; j++) {
resultNumberAlphabets[++l] = stringAlphabets[j];
}
}
}

private void printResults(char result[]) {
for (int i = 0; i < result.length; i++) {
System.out.print(result[i]);
if ((i + 1) == result.length) {
System.out.println(".");
} else {
System.out.print(", ");
}
}
}}


There are a few more optimizations, for example, your printResults() method can be optimized to work without the if-/else-condition. Because you are only printing ". " at the end, you can simply skip the last iteration and print ", " otherwise as follows:

private void printResults(char result[]) {
for (int i = 0; i < result.length - 1; i++) {
System.out.print(result[i] + ", ");
}
System.out.println(".");
}