Solución:
Utilice un bucle triple:
for (int i=0; i < operators.length; ++i) {
for (int j=0; j < operators.length; ++j) {
for (int k=0; k < operators.length; ++k) {
System.out.println(numbers[0] + operators[i] + numbers[1] + operators[j] +
numbers[2] + operators[k] + numbers[3]);
}
}
}
Básicamente, desea tomar el producto cruzado del vector de operadores (si fuera un vector). En Java, esto se traduce en un conjunto de bucles triplemente anidados.
Si bien la solución @TimBiegeleisen funcionaría a las mil maravillas, su complejidad podría ser un problema. El mejor enfoque sería un código como este:
static void combinationUtil(
int[] arr, int n, int r, int index, int[] data, int i) {
// Current combination is ready to be printed, print it
if (index == r) {
for (int j = 0; j < r; j++)
System.out.print(data[j] + " ");
System.out.println("");
return;
}
// When no more elements are there to put in data[]
if (i >= n)
return;
// current is included, put next at next location
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1, data, i + 1);
// current is excluded, replace it with next (Note that
// i+1 is passed, but index is not changed)
combinationUtil(arr, n, r, index, data, i + 1);
}
// The main function that prints all combinations of size r
// in arr[] of size n. This function mainly uses combinationUtil()
static void printCombination(int arr[], int n, int r) {
// A temporary array to store all combination one by one
int data[] = new int[r];
// Print all combination using temprary array 'data[]'
combinationUtil(arr, n, r, 0, data, 0);
}
Fuente: GeeksForGeeks y mi IDE 🙂
Esto suena como un caso de libro de texto para una solución recursiva:
public static void combineAndPrint(String[] pieces, String[] operators) {
if (pieces.length < 1) {
// no pieces? do nothing!
} else if (pieces.length == 1) {
// just one piece? no need to join anything, just print it!
System.out.println(pieces[0]);
} else {
// make a new array that's one piece shorter
String[] newPieces = new String[pieces.length - 1];
// copy all but the first two pieces into it
for (int i = 2; i < pieces.length; i++) {
newPieces[i - 1] = pieces[i];
}
// combine the first two pieces and recurse
for (int i = 0; i < operators.length; i++) {
newPieces[0] = pieces[0] + operators[i] + pieces[1];
combineAndPrint(newPieces, operators);
}
}
}
public static void main(String[] args) {
String[] operators = {"+", "-", "*"};
String[] numbers = {"48", "24", "12", "6"};
combineAndPrint(numbers, operators);
}
¡Pruébelo en línea!
Por cierto, para generalizar este método para que pueda hacer más cosas con las expresiones generadas que solo imprimirlas, le recomendaría que acepte un extra Consumer<String>
parámetro. Es decir, podría reescribir la declaración del método como:
public static void combine(String[] pieces, String[] operators, Consumer<String> consumer) {
y reemplace el System.out.println(pieces[0])
con consumer.accept(pieces[0])
y la llamada recursiva a combineAndPrint(newPieces, operators)
con combine(newPieces, operators, consumer)
. Luego simplemente llámelo desde su método principal, por ejemplo, como:
combine(numbers, operators, s -> System.out.println(s));
¡Pruébelo en línea!
(Por supuesto, hacerlo de esta manera más flexible requiere una versión de Java algo moderna, Java 8 o posterior, para ser específicos, mientras que el primer ejemplo que mostré anteriormente debería funcionar incluso en versiones antiguas hasta Java 1.0. Tal vez en alguna versión futura de Java obtendremos el soporte adecuado para corrutinas y generadores, como Python y Kotlin e incluso JS moderno ya lo tienen, y entonces ni siquiera tendremos que pasar al consumidor más.)