Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cartesian product of two arrays

How is it possible to do the Cartesian product using two arrays?

A={1,2,3}
B={2,3,4}
C={(1,2),(1,3),(1,4),(2,2),(2,3),(2,4),(3,2),(3,3),(3,4)}

This is the code I was using, but I always get a IndexOutOfBoundException.

public int[] cartesianProduct(int[] s1, int[] s2) {
    ArrayList<Integer> list = new ArrayList<>();
    for (int i = 0; i < s1.length; i++) {
        for (int v1 : s1) {
            for (int v2 : s2) {
                list.add(s1[i], s2[i]);
            }
        }
    }
    int[] result = new int[list.size()];
    int k = 0;
    for (int i : list) {
        result[k++] = i;
    }
    return result;
}
like image 459
Michael Lee Avatar asked Sep 05 '25 21:09

Michael Lee


2 Answers

To get Cartesian product with Java 8:

int[] A = {1, 2, 3};
int[] B = {2, 3, 4};
int[][] AB = Arrays.stream(A).boxed()
        .flatMap(ai -> Arrays.stream(B).boxed()
                .map(bi -> new int[]{ai, bi}))
        .toArray(int[][]::new);
System.out.println("Cartesian product:\n" + Arrays.deepToString(AB));

Output:

Cartesian product:
[[1, 2], [1, 3], [1, 4], [2, 2], [2, 3], [2, 4], [3, 2], [3, 3], [3, 4]]
like image 153
Saravana Avatar answered Sep 08 '25 12:09

Saravana


The elements of the output array should be pairs of integers, therefore an int array cannot be the type of the output, and you can't use a List<Integer> to collect the data.

One way to represent each pair of numbers is an int array of two elements. This way the output would be a 2D array, and the List used to collect the data can be a List<int[]>:

public int[][] cartesianProduct(int[] s1, int[] s2) {
    List<int[]> list = new ArrayList<>();
    for (int v1 : s1) {
        for (int v2 : s2) {
            list.add(new int[]{v1, v2});
        }
    }
    int[][] result = new int[list.size()][2];
    int k = 0;
    for (int[] i : list) {
        result[k++] = i;
    }
    return result;
}
like image 42
Eran Avatar answered Sep 08 '25 10:09

Eran