aroth 指出,使用数字计数器方法更快。为了使这更快,您可以对最后一位数字使用内部循环和对其余数字使用计数器的组合(因此数字的数量可以是可变的)
public static void main(String... args) {
long start = System.nanoTime();
int letters = 26;
int count = 6;
final int combinations = (int) Math.pow(letters, count);
char[] chars = new char[count];
Arrays.fill(chars, 'a');
final int last = count - 1;
OUTER:
while (true) {
for (chars[last] = 'a'; chars[last] <= 'z'; chars[last]+=2) {
newComination(chars);
chars[last]++;
newComination(chars);
}
UPDATED:
{
for (int i = last - 1; i >= 0; i--) {
if (chars[i]++ >= 'z')
chars[i] = 'a';
else
break UPDATED;
}
// overflow;
break OUTER;
}
}
long time = System.nanoTime() - start;
System.out.printf("Took %.3f seconds to generate %,d combinations%n", time / 1e9, combinations);
}
private static void newComination(char[] chars) {
}
打印
Took 0.115 seconds to generate 308,915,776 combinations
注意:循环是如此简单,JIT 很可能会消除关键代码片段(在内联 newCombination 之后),其如此快速的原因是它并没有真正计算每个组合。
生成组合的更简单方法。
long start = System.nanoTime();
int letters = 26;
int count = 6;
final int combinations = (int) Math.pow(letters, count);
StringBuilder sb = new StringBuilder(count);
for (int i = 0; i < combinations; i++) {
sb.setLength(0);
for (int j = 0, i2 = i; j < count; j++, i2 /= letters)
sb.insert(0, (char) ('a' + i2 % letters));
// System.out.println(sb);
}
long time = System.nanoTime() - start;
System.out.printf("Took %.3f seconds to generate %,d combinations%n", time / 1e9, combinations);
打印
aaaa
aaab
aaac
....
zzzx
zzzy
zzzz
Took 0.785 seconds to generate 456,976 combinations
它大部分时间都在等待屏幕更新。 ;)
如果您注释掉打印组合的行,并将计数增加到 5 和 6
Took 0.671 seconds to generate 11,881,376 combinations
Took 15.653 seconds to generate 308,915,776 combinations