Skip to content

Instantly share code, notes, and snippets.

@Sothatsit
Created January 12, 2018 08:33
Show Gist options
  • Select an option

  • Save Sothatsit/e9e295112e15eff63d010a7a45b5a351 to your computer and use it in GitHub Desktop.

Select an option

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...
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