I wanted to compare the LCS of two files from their binary, therefore i used the usual LCS source code, and using the GenStr command to change the bytes of the file to String first. The problem is, I received memory out of bound error because comparing String has limit, therefore i am planning to use array that stores the bytes then compare it. Is it possible to use LCS algorithm to compare two arrays of bytes?
EDIT:
public static byte[] Compare(byte[] x, byte[] y) {
int i, j;
final int x_length = x.length;
final int y_length = y.length;
int n = 2048;
int m = 2048;
// D[i][j] = direction, L[i][j] = Length of LCS
int[][] D = new int[n + 1][m + 1];
byte[][] L = new byte[n + 1][m + 1]; // { 1, 2, 3 }
// D[i][0] = 0 for 0<=i<=n
// D[0][j] = 0 for 0<=j<=m
for (i = 1; i <= n; i++) {
for (j = 1; j <= m; j++) {
if (x[i - 1] == y[j - 1]) {
D[i][j] = D[i - 1][j - 1] + 1;
L[i][j] = 1;
} else if (D[i - 1][j] >= D[i][j - 1]) {
D[i][j] = D[i - 1][j];
L[i][j] = 2;
} else {
D[i][j] = D[i][j - 1];
L[i][j] = 3;
}
}
}
// Backtrack
ByteArrayOutputStream lcs = new ByteArrayOutputStream();
i = n;
j = m;
while (i != 0 && j != 0) {
switch (L[i][j]) {
case 1: // diagonal
lcs.write(x[i - 1]); // Unreversed LCS
--i;
--j;
break;
case 2: // up
--i;
break;
case 3: // backward
--j;
break;
}
}
byte[] result = lcs.toByteArray();
// Reverse:
for (i = 0, j = result.length - 1; i < j; ++i, --j) {
byte b = result[i];
result[i] = result[j];
result[j] = b;
}
return result;
//While not end of file
while(n < x_length && m < y_length){
if(n+2048 < x.length){
n = n+2048;
} else {
n = x.length;
}
if(m+2048 < y.length){
m = m+2048;
} else {
m = y.length;
}
// D[i][j] = direction, L[i][j] = Length of LCS
int[][] D_new = new int[n + 1][m + 1];
byte[][] L_new = new byte[n + 1][m + 1]; // { 1, 2, 3 }
// D[i][0] = 0 for 0<=i<=n
// D[0][j] = 0 for 0<=j<=m
for (i = i+2048; i <= n; i++) {
for (j = j+2048; j <= m; j++) {
if (x[i - 1] == y[j - 1]) {
D_new[i][j] = D_new[i - 1][j - 1] + 1;
L_new[i][j] = 1;
} else if (D_new[i - 1][j] >= D_new[i][j - 1]) {
D_new[i][j] = D_new[i - 1][j];
L_new[i][j] = 2;
} else {
D_new[i][j] = D_new[i][j - 1];
L_new[i][j] = 3;
}
}
}
// Backtrack
ByteArrayOutputStream lcs_next = new ByteArrayOutputStream();
i = n;
j = m;
while (i != 0 && j != 0) {
switch (L[i][j]) {
case 1: // diagonal
lcs_next.write(x[i - 1]); // Unreversed LCS
--i;
--j;
break;
case 2: // up
--i;
break;
case 3: // backward
--j;
break;
}
}
byte[] result_new = lcs_next.toByteArray();
// Reverse:
for (i = 0, j = result_new.length - 1; i < j; ++i, --j) {
byte b = result_new[i];
result_new[i] = result_new[j];
result_new[j] = b;
}
return result_new;
Arrays.fill(D_new, null);
Arrays.fill(L_new, null);
Arrays.fill(result_new, null);
lcs_next.reset();
}
}
I tried, but haven't been able to check if this can be used or not, because of some errors.
Questions:
- how do you append the lcs in line (
return result
) and line (return result_new
)? - how do you clear the array so i can use it over and over again with different input?
(
Array.fill(D_new, null)
andArray.fill(L_new, null)
doesn't work)?
Thank you in advance