Вам не нужна рекурсия или сильно вложенные петли или даже для создания / хранения всего массива перестановок в памяти.
Поскольку число перестановок является произведением длин каждой из массивы (назовем это numPerms
), вы можете создать функцию getPermutation(n)
, которая возвращает уникальную перестановку между индексами 0
и numPerms - 1
, вычисляя индексы, необходимые для извлечения своих символов, на основе n
.
Как это делается? Если вы думаете о создании перестановок на массивах, каждый из которых содержит: [0, 1, 2, ... 9], это очень просто ... 245-я перестановка (n = 245) - это «245», скорее интуитивно, или:
arrayHundreds[Math.floor(n / 100) % 10]
+ arrayTens[Math.floor(n / 10) % 10]
+ arrayOnes[Math.floor(n / 1) % 10]
Усложнение в вашей проблеме заключается в том, что размеры массива различаются. Мы можем обойти это, заменив n/100
, n/10
и т. Д. Другими делителями. С этой целью мы можем легко вычислить массив делителей. В приведенном выше примере делитель 100 был равен arrayTens.length * arrayOnes.length
. Поэтому мы можем вычислить делитель для данного массива как произведение длин оставшихся массивов. У самого последнего массива всегда есть делитель 1. Кроме того, вместо modding на 10 мы модифицируем длину текущего массива.
Пример кода ниже:
var allArrays = [first, second, third, ...];
// Pre-calculate divisors
var divisors = [];
for (var i = allArrays.length - 1; i >= 0; i--) {
divisors[i] = divisors[i + 1] ? divisors[i + 1] * allArrays[i + 1].length : 1;
}
function getPermutation(n) {
var result = "", curArray;
for (var i = 0; i < allArrays.length; i++) {
curArray = allArrays[i];
result += curArray[Math.floor(n / divisors[i]) % curArray.length];
}
return result;
}
Вы можете сделать флаг перед возвратом
public static void cat(File file) {
boolean readAll = false;
try (RandomAccessFile input = new RandomAccessFile(file, "r")){
String line = null;
while ((line = input.readLine()) != null) {
System.out.println(line);
}
readAll = true;
return;
} catch(FileNotFoundException a){
;//do something to recover from this exception.
}catch(IOException b){
;//distinguish between close and readLine exception.
if (readAll) ...
}
}