Найти все верхний/нижний регистр сочетаний слов


Для каждого слова есть 2^n различных способов написание слова, если принять во внимание Верхний и нижний регистр букв. Например, "слово", мы можем написать;

  • слово
  • Слово
  • слово
  • Слово
  • слово
  • Слово
  • и т. д.

Я написал этот код, чтобы вычислить все комбинации. Есть ли способ я могу улучшить производительность? Профилирование мне подсказывает, что этот метод занимает 99,9% времени выполнения моей программы (который измеряет силу пароля).

String word = "word";
int combinations = 1 << word.length();   

for (int i=0; i<combinations; i++) {
  StringBuilder buf = new StringBuilder(word);
  for (int j=0; j<word.length(); j++) {
    if ((i & 1<<j) != 0) {
      String s = word.substring(j, j+1).toUpperCase();
      buf.replace(j, j+1, s);
    }
  }
  System.out.println(buf);
}


7125
2
задан 30 июня 2011 в 10:06 Источник Поделиться
Комментарии
1 ответ

public static void comb(String word) {
int combinations = 1 << word.length();
char[][] chars = { word.toLowerCase().toCharArray(),
word.toUpperCase().toCharArray() };
char[] result = new char[word.length()];

for (int i = 0; i < combinations; i++) {
for (int j = 0; j < word.length(); j++) {
result[j] = chars[(i >> j) & 1][j];
}
System.out.println(new String(result));
}
}

[Править]

Я сделал некоторые профилирования, и моя версия мне кажется немного лучше, и в следующей версии будет даже немного быстрее:

public static void comb(String word) {
word = word.toLowerCase();
int combinations = 1 << word.length();
for (int i = 0; i < combinations; i++) {
char[] result = word.toCharArray();
for (int j = 0; j < word.length(); j++) {
if (((i >> j) & 1) == 1 ) {
result[j] = Character.toUpperCase(word.charAt(j));
}
}
System.out.println(new String(result));
}
}

Однако, все версии до сих пор находятся в тех же пределах и не изменить что-то существенное, потому что система.из.код println доминирует результативность.

[Править 2]

Алгоритм на самом деле не имеет большого значения, в системе.из.метод println последствия слишком тяжелые. Коллекция все в то StringBuilder и вызов системе.из.код println не поможет. Однако, удивительно, но мой профайлер мне говорит, что эта простая рекурсивная версия работает лучше:

public static void comb4(String word) {
comb4(word,new char[word.length()],0);
}

private static void comb4(String word, char[] accu, int index) {
if(index == word.length()) {
System.out.println(accu);
} else {
char ch = word.charAt(index);
accu[index] = Character.toLowerCase(ch);
comb4(word, accu , index+1);
accu[index] = Character.toUpperCase(ch);
comb4(word, accu, index+1);
}
}

4
ответ дан 30 июня 2011 в 01:06 Источник Поделиться