У меня есть идея, как решить эту проблему с помощью итеративного алгоритма без рекурсии:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Main
{
static List<int[]> getAll(int n, int[] x)
{
List<int[]> combinations = new ArrayList<>();
// First step (0)
// Create initial combinations, filled with the first number.
for (int number = 0; number < x.length; number++)
{
int[] array = new int[n]; // the final size of each array is already known
array[0] = x[number]; // fill the first number
combinations.add(array);
}
// In each following step, we add one number to each combination
for (int step = 1; step < n; step++)
{
// Backup the size because we do not want to process
// the new items that are added by the following loop itself.
int size = combinations.size();
// Add one number to the existing combinations
for (int combination = 0; combination < size; combination++)
{
// Add one number to the existing array
int[] array = combinations.get(combination);
array[step] = x[0];
// For all additional numbers, create a copy of the array
for (int number = 1; number < x.length; number++)
{
int[] copy = Arrays.copyOf(array, array.length);
copy[step] = x[number];
combinations.add(copy);
}
}
}
return combinations;
}
public static void main(String[] args)
{
int[] x = {3, 5, 7};
int n = 3;
// Calculate all possible combinations
List<int[]> combinations = getAll(n, x);
// Print the result
for (int[] combination : combinations)
{
System.out.println(Arrays.toString(combination));
}
}
}
Мои мысли были:
Каждый массив имеет хорошо известный размер (n), поэтому я можно сразу создать их с окончательным размером.
Для первого шага (0) я заполняю массивы числами от x, оставляя их оставшиеся элементы неинициализированными:
[3, ?, ?]
[5, ?, ?]
[7, ?, ?]
Затем я заполните оставшиеся элементы каждого массива шаг за шагом. Но при этом количество возможных комбинаций увеличивается, поэтому я делаю копии существующих массивов и добавляю все возможные комбинации в список результатов.
Следующий шаг (1) заполняет второй столбец:
[3, ?, ?] update to [3, 3, ?]
copy to [3, 5, ?]
copy to [3, 7, ?]
[5, ?, ?] update to [5, 3, ?]
copy to [5, 5, ?]
copy to [5, 7, ?]
[7, ?, ?] update to [7, 3, ?]
copy to [7, 5, ?]
copy to [7, 7, ?]
Следующий шаг заполняет третий столбец:
[3, 3, ?] update to [3, 3, 3]
copy to [3, 3, 5]
copy to [3, 3, 7]
[3, 5, ?] update to [3, 5, 3]
copy to [3, 5, 5]
copy to [3, 5, 7]
[3, 7, ?] update to [3, 7, 3] ... and so on
[5, 3, ?]
[5, 5, ?]
[5, 7, ?]
[7, 3, ?]
[7, 5, ?]
[7, 7, ?]
В моем коде используются массивы int
, но это работает также с double
. Я думаю, что алгоритм будет работать с любым количеством итераций.