2020-01-15 22:30:09 +01:00
|
|
|
package cd;
|
2020-01-15 22:18:07 +01:00
|
|
|
|
|
|
|
// NOTE: This code was adapted from the code found at
|
|
|
|
// http://www.cs.princeton.edu/introcs/96optimization/Diff.java.html
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* Compilation: javac Diff
|
|
|
|
* Execution: java Diff filename1 filename2
|
|
|
|
* Dependencies: In.java
|
|
|
|
*
|
|
|
|
* Reads in two files and compute their diff.
|
|
|
|
* A bare bones version.
|
|
|
|
*
|
|
|
|
* % java Diff input1.txt input2.txt
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Limitations
|
|
|
|
* -----------
|
|
|
|
* - Could hash the lines to avoid potentially more expensive
|
|
|
|
* string comparisons.
|
|
|
|
*
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
public class Diff {
|
|
|
|
|
|
|
|
public static String computeDiff(String in0, String in1) {
|
|
|
|
StringBuffer out = new StringBuffer();
|
|
|
|
|
|
|
|
// break into lines of each file
|
|
|
|
String[] x = in0.split("\\n");
|
|
|
|
String[] y = in1.split("\\n");
|
|
|
|
|
|
|
|
// number of lines of each file
|
|
|
|
int M = x.length;
|
|
|
|
int N = y.length;
|
|
|
|
|
|
|
|
// opt[i][j] = length of LCS of x[i..M] and y[j..N]
|
|
|
|
int[][] opt = new int[M+1][N+1];
|
|
|
|
|
|
|
|
// compute length of LCS and all subproblems via dynamic programming
|
|
|
|
for (int i = M-1; i >= 0; i--) {
|
|
|
|
for (int j = N-1; j >= 0; j--) {
|
|
|
|
if (x[i].equals(y[j]))
|
|
|
|
opt[i][j] = opt[i+1][j+1] + 1;
|
|
|
|
else
|
|
|
|
opt[i][j] = Math.max(opt[i+1][j], opt[i][j+1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// recover LCS itself and print out non-matching lines to standard output
|
|
|
|
boolean lineNumber = false;
|
|
|
|
int i = 0, j = 0;
|
|
|
|
while(i < M && j < N) {
|
|
|
|
if (x[i].equals(y[j])) {
|
|
|
|
i++;
|
|
|
|
j++;
|
|
|
|
lineNumber = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!lineNumber) {
|
|
|
|
out.append(String.format(
|
|
|
|
"At line %3d / %3d:\n", i+1, j+1));
|
|
|
|
lineNumber = true;
|
|
|
|
}
|
|
|
|
assert lineNumber;
|
|
|
|
if (opt[i+1][j] >= opt[i][j+1])
|
|
|
|
out.append("< " + x[i++] + "\n");
|
|
|
|
else
|
|
|
|
out.append("> " + y[j++] + "\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// dump out one remainder of one string if the other is exhausted
|
|
|
|
if (!lineNumber) {
|
|
|
|
out.append(String.format("Line %3d / %3d:\n", i+1, j+1));
|
|
|
|
}
|
|
|
|
while(i < M || j < N) {
|
|
|
|
if (i == M)
|
|
|
|
out.append("> " + y[j++] + "\n");
|
|
|
|
else if (j == N)
|
|
|
|
out.append("< " + x[i++] + "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return out.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|