My main objective is to return if all elements, int[ ], of a 2D Array ,int[ ][ ], are present in another 2D Array.
I already tried to use Arrays.deepEquals()
but in this case, the order of the elements would matter and that’s not the purpose.
- Int[ ][ ] arrays wouldn’t be longer than 15, for example.
- Int[ ][ ] arrays have always the same length.
- Int[ ][ ] arrays order doesn’t matter, but Int[ ] arrays does.
- Int[ ] arrays would always be a pair.
Expected:
int[][] array1 = {{1, 2}, {2, 2}, {0, 1}, {3,4}} // Main Array int[][] array2 = {{0, 1}, {2, 2}, {3,4} {1, 2}}} // Expected: true int[][] array3 = {{6, 3}, {1, 2}, {7,4} {0, 1}}} // Expected: false
This is my solution/try:
// Check if an int[] array (element) belongs to an int[][] array. public static boolean inVector(int[][] 2dArray, int[] 1dArray) { for (int i = 0; i < 2dArray.length; i++) { for (int j = 0; j < 2dArray[i].length; j++) { if (1dArray[0] == 2dArray[i][0] && 1dArray[1] == 2dArray[i][1]) { return true; } } } return false; } // Check if all int[] arrays of an int[][] belong to another int[][] array. // This is not working properly public boolean allBelongs() { boolean belongs = false; for (int i = 0; i < array1.length; i++) { if (inVector(array1, array2()[i])) { belongs = true; } else { belongs = false; } } return belongs; }
EDIT: I solved the problem reversing the logic of the solution. Posted own answer.
Advertisement
Answer
You can use IntBuffer
which can wrap an int[]
array and provide the equals
and hashCode
implementations reflecting the array’s content.
public static boolean sameSubArrays(int[][] array1, int[][] array2) { if(array1 == array2) return true; HashSet<IntBuffer> set = new HashSet<>(); for(int[] a: array1) set.add(IntBuffer.wrap(a)); for(int[] a: array2) if(!set.contains(IntBuffer.wrap(a))) return false; return true; }
This is simple and runs in linear time, hence, can cope with large arrays. It has the expected result for your test case.
int[][] array1 = {{1, 2}, {2, 2}, {0, 1}, {3,4}}; int[][] array2 = {{0, 1}, {2, 2}, {3, 4}, {1, 2}}; System.out.println(sameSubArrays(array1, array2)); // true
But it does not consider duplicates. If the number of occurrences must match for sub arrays with the same contents, you have to expand the solution to use a map to count the occurrences.
public static boolean sameSubArrays(int[][] array1, int[][] array2) { if(array1 == array2) return true; if(array1.length != array2.length) return false; HashMap<IntBuffer, Integer> map = new HashMap<>(); for(int[] a: array1) map.merge(IntBuffer.wrap(a), 1, Integer::sum); for(int[] a: array2) if(map.merge(IntBuffer.wrap(a), -1, Integer::sum) < 0) return false; return true; }
Since your example has no duplicates, it still has the same result.