这比较了使用循环和递归。我一般不喜欢 Java 中的递归,但在这种情况下,它更干净、更快。
private static volatile int dontOptimiseAway;
public static void main(String[] args) throws IOException, ClassNotFoundException {
for (int i = 1; i <= 6; i++) {
long comb = testCombinations(i, 'a', 'z');
long iter = testIteration(i, 'a', 'z');
System.out.printf("%d: Comb: %.3f secs, loops: %.3f%n", i, comb / 1e9, iter / 1e9);
}
}
private static long testCombinations(int maxLetters, char min, char max) {
long start = System.nanoTime();
for (int i = 1; i <= maxLetters; i++)
combinations(i, min, max);
return System.nanoTime() - start;
}
public static void combinations(int length, char min, char max) {
combinations0(new char[length], 0, min, max);
}
private static void combinations0(char[] chars, int i, char min, char max) {
if (i >= chars.length) {
doStuff(chars);
} else {
for (char ch = min; ch <= max; ch++) {
chars[i] = ch;
combinations0(chars, i + 1, min, max);
}
}
}
private static void doStuff(char[] chars) {
dontOptimiseAway = chars.length;
}
private static long testIteration(int maxLetters, char min, char max) {
long start = System.nanoTime();
for (int i = 1; i <= maxLetters; i++)
loops(i, min, max);
return System.nanoTime() - start;
}
public static void loops(int length, char min, char max) {
int numDifferentChars = max - min + 1;
long numPossibilities = (long) Math.pow(numDifferentChars, length);
char[] chars = new char[length];
for (long i = 0; i < numPossibilities; i++) {
long chr = i;
for (int j = 0; j < length; j++) {
chars[j] = (char) (chr % numDifferentChars + min);
chr /= numDifferentChars;
}
doStuff(chars);
}
}
印刷
1: Comb: 0.000 secs, loops: 0.000
2: Comb: 0.000 secs, loops: 0.000
3: Comb: 0.003 secs, loops: 0.004
4: Comb: 0.006 secs, loops: 0.025
5: Comb: 0.116 secs, loops: 0.793
6: Comb: 3.856 secs, loops: 25.101