В качестве примера мы прочесываем перестановки целого числа 123456789. Вдохновленный Алгоритм кучи, у нас есть следующие
public static ArrayList<String> comb(char[] seq, int n, ArrayList<String> box){
if (n == 1){
if (isSquare(Integer.valueOf(String.valueOf(seq)))) {
box.add(String.valueOf(seq));
}
} else {
for(int i=0; i<n; i++){
comb(seq,n-1, box);
int j;
if ((n%2)==0) {
j = i;
} else {
j = 0;
}
char temp = seq[n-1];
seq[n-1] = seq[j];
seq[j] = temp;
}
}
return box;
}
В данном случае нас интересует, является ли конкретная перестановка квадратом целого числа. Осуществлено
public static boolean isSquare(int n) {
if ((n%10)==2 || (n%10) ==3 || (n%10)==7 || (n%10) == 8) {
return false;
} else if ( (Math.sqrt(n)) % 1 ==0) {
return true;
} else {
return false;
}
}
Однако, чтобы иметь возможность использовать comb, я должен инициализировать пустой массив вне метода. Что мне делать, чтобы избежать необходимости в глобальной переменной? Я все еще хотел бы получить box со всеми решениями. Я понимаю, что моя ошибка заключается в параметризации comb.
Проблема на самом деле не в необходимости создания массива вне метода, вы можете это обойти. Но проблема в том, что вы изменяете ArrayList а также в массив seq, изменяя (содержимое) ваших параметров, как правило, не одобряют, потому что вызывающий может / не ожидает этого.




Создайте функцию, которая «обертывает» исходную рекурсивную функцию, предоставляет ей все необходимые параметры и при необходимости создает копии объектов:
Допустим, вы переименовали свою функцию comb(...) в combRecursive(...) для удобства именования.
public static ArrayList<String> comb(char[] seq, int n){
char[] seqCopy = Arrays.copyOf(seq, seq.length);
return combRecursive(seqCopy, n, new ArrayList());
}
«Я должен инициализировать пустой массив вне метода. Что мне делать, чтобы избежать необходимости в глобальной переменной?» Передайте его как параметр.