Created
January 12, 2018 08:33
-
-
Save Sothatsit/e9e295112e15eff63d010a7a45b5a351 to your computer and use it in GitHub Desktop.
I tried to make an array diff function. It doesn't work very fast when the arrays get large...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static void main(String[] args) { | |
| System.out.println("\nchange"); | |
| diff(new int[] {1, 1, 1, 4, 5}, | |
| new int[] {1, 1, 1, 6, 5}); | |
| System.out.println("\nadd"); | |
| diff(new int[] {1, 1, 1, 4, 5}, | |
| new int[] {1, 1, 1, 6, 4, 5, 4, 5, 6}); | |
| System.out.println("\nremove"); | |
| diff(new int[] {1, 1, 1, 4, 5}, | |
| new int[] {1, 1, 1, 5}); | |
| System.out.println("\nanother one"); | |
| diff(new int[] {1, 2, 2, 1}, | |
| new int[] {1, 2, 1, 2}); | |
| System.out.println("\nlarge"); | |
| int size = 30000; | |
| int[] one = new int[size]; | |
| int[] two = new int[size]; | |
| Random random = new Random(); | |
| for (int index = 0; index < size; ++index) { | |
| one[index] = two[index] = random.nextInt(1000); | |
| } | |
| for (int index = 0; index < 5; ++index) { | |
| two[index] = random.nextInt(1000); | |
| } | |
| diff(one, two); | |
| } | |
| private static class Sub { | |
| public final int from; | |
| public final int to; | |
| public Sub(int from, int to) { | |
| if (to < from) throw new IllegalArgumentException("to must be >= from"); | |
| this.from = from; | |
| this.to = to; | |
| } | |
| } | |
| private static class DualSub { | |
| public final Sub from; | |
| public final Sub to; | |
| public DualSub(Sub from, Sub to) { | |
| this.from = from; | |
| this.to = to; | |
| } | |
| } | |
| private static boolean isCleared(boolean[] clearedRows, boolean[] clearedCols, int row, int col, int length) { | |
| for (int index = 0; index < length; ++index) { | |
| if (clearedRows[row - index]) | |
| return true; | |
| if (clearedCols[col - index]) | |
| return true; | |
| } | |
| return false; | |
| } | |
| private static void clear(boolean[] clearedRows, boolean[] clearedCols, int row, int col, int length) { | |
| for (int index = 0; index < length; ++index) { | |
| clearedRows[row - index] = true; | |
| clearedCols[col - index] = true; | |
| } | |
| } | |
| public static void diff(int[] fromLine, int[] toLine) { | |
| long start = System.nanoTime(); | |
| int cols = fromLine.length; | |
| int rows = toLine.length; | |
| int[][] table = new int[rows + 1][cols + 1]; | |
| // Build table that contains the length of sub-arrays | |
| for (int col = 1; col <= cols; ++col) { | |
| for (int row = 1; row <= rows; ++row) { | |
| int from = fromLine[col - 1]; | |
| int to = toLine[row - 1]; | |
| if (from == to) { | |
| table[row][col] = table[row - 1][col - 1] + 1; | |
| } | |
| } | |
| } | |
| List<DualSub> subs = new ArrayList<>(); | |
| boolean[] clearedRows = new boolean[rows]; | |
| boolean[] clearedCols = new boolean[cols]; | |
| // Search the table for common sub-arrays | |
| int maxSize = Math.max(cols, rows); | |
| for (int index = 0; index < maxSize; ++index) { | |
| int max = 0; | |
| int maxRow = 0; | |
| int maxCol = 0; | |
| int currentRow = Math.max(1, rows - index); | |
| int currentCol = Math.max(1, cols - index); | |
| if (!clearedRows[currentRow - 1]) { | |
| for (int row = currentRow; row <= rows; ++row) { | |
| int value = table[row][currentCol]; | |
| if (value > max && !isCleared(clearedRows, clearedCols, row - 1, currentCol - 1, value)) { | |
| max = value; | |
| maxRow = row; | |
| maxCol = currentCol; | |
| } | |
| } | |
| } | |
| if (!clearedCols[currentCol - 1]) { | |
| for (int col = currentCol + 1; col <= cols; ++col) { | |
| int value = table[currentRow][col]; | |
| if (value > max && !isCleared(clearedRows, clearedCols, currentRow - 1, col - 1, value)) { | |
| max = value; | |
| maxRow = currentRow; | |
| maxCol = col; | |
| } | |
| } | |
| } | |
| if (max != 0) { | |
| clear(clearedRows, clearedCols, maxRow - 1, maxCol - 1, max); | |
| Sub fromSub = new Sub(maxCol - max, maxCol - 1); | |
| Sub toSub = new Sub(maxRow - max, maxRow - 1); | |
| DualSub sub = new DualSub(fromSub, toSub); | |
| subs.add(0, sub); | |
| } | |
| } | |
| long end = System.nanoTime(); | |
| System.out.println("time: " + ((end - start) / 1000000d) + "ms"); | |
| if (fromLine.length <= 50 && toLine.length <= 50) { | |
| for (int index = 0; index < subs.size(); ++index) { | |
| DualSub sub = subs.get(index); | |
| if (index != 0) { | |
| System.out.print(" ... "); | |
| } | |
| int[] array = Arrays.copyOfRange(fromLine, sub.from.from, sub.from.to + 1); | |
| System.out.print(Arrays.toString(array)); | |
| } | |
| System.out.println(); | |
| for (int rowIndex = 1; rowIndex < table.length; ++rowIndex) { | |
| int[] line = table[rowIndex]; | |
| for (int index = 1; index < line.length; ++index) { | |
| if (index != 1) { | |
| System.out.print(" "); | |
| } | |
| System.out.print(line[index]); | |
| } | |
| System.out.println(); | |
| } | |
| } else { | |
| System.out.println("table too big to display"); | |
| } | |
| } | |
| public static void diffLines(Polyline fromLine, Polyline toLine) { | |
| List<Point2D.Double> fromPoints = fromLine.getPoints(); | |
| List<Point2D.Double> toPoints = toLine.getPoints(); | |
| int fromSize = fromPoints.size(); | |
| int toSize = toPoints.size(); | |
| int[][] table = new int[fromSize + 1][toSize + 1]; | |
| for (int fromIndex = 1; fromIndex < fromPoints.size(); ++fromIndex) { | |
| for (int toIndex = 1; toIndex < toPoints.size(); ++toIndex) { | |
| Point2D.Double from = fromPoints.get(fromIndex); | |
| Point2D.Double to = toPoints.get(toIndex); | |
| if (from.equals(to)) { | |
| table[fromIndex][toIndex] = table[fromIndex - 1][toIndex - 1] + 1; | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment