UVa 531 - Compromise
by Abhijeet Kashnia
Here's my solution to the variation of longest common subsequence problem mentioned at Uva problem 531 called Compromise.
It is still too long for my liking, and I don't exactly follow the complete steps of submitting the solution to the online judge. When working with Java, I tend to get a lot of timeout errors. That put me off so much that now I only try to solve the problem to my liking, and if I am satisfied with the algorithm, I can live without getting formal approval from the judge.
<code>
package uva;
public class Compromise
{
char[][] res;
int[][] dp;
static String[] pattern1;
static String[] pattern2;
public static void main(String[] args)
{
String string1 = "die einkommen der landwirte sind fuer die abgeordneten ein buch mit sieben siegeln um dem abzuhelfen muessen dringend"
+ " alle subventionsgesetze verbessert werden";
String string2 = "die steuern auf vermoegen und einkommen sollten nach meinung der abgeordneten nachdruecklich erhoben werden dazu muessen"
+ " die kontrollbefugnisse der finanzbehoerden dringend verbessert werden";
pattern1 = string1.split(" ");
pattern2 = string2.split(" ");
new Compromise().compromise(pattern1, pattern2);
}
private void compromise(String[] pattern1, String[] pattern2)
{
dp = new int[pattern1.length + 1][pattern2.length + 1];
res = new char[pattern1.length + 1][pattern2.length + 1];
for (int i = 1; i <= pattern1.length; i++)
dp[i][0] = 0;
for (int j = 0; j <= pattern2.length; j++)
dp[0][j] = 0;
// First write the solution for characters only.
for (int i = 1; i <= pattern1.length; i++)
for (int j = 1; j <= pattern2.length; j++)
{
if (pattern1[i - 1].equals(pattern2[j - 1]))
{
dp[i][j] = dp[i - 1][j - 1] + 1;
res[i][j] = 'D'; // from top left, means diagonal
} else if (dp[i - 1][j] >= dp[i][j - 1])
{
dp[i][j] = dp[i - 1][j];
res[i][j] = 'T'; // from top
} else
{
dp[i][j] = dp[i][j - 1];
res[i][j] = 'L'; // from left
}
}
System.out.println("Final matrix is: ");
printIntMatrix(dp);
System.out.println("Result is: ");
printCharMatrix(res);
printCommonSequence(pattern1.length, pattern2.length);
System.out.println("\nLength is "
+ dp[pattern1.length][pattern2.length]);
}
private void printIntMatrix(int[][] matrix)
{
for (int i = 0; i <= pattern1.length; i++)
{
for (int j = 0; j < pattern2.length; j++)
{
System.out.print(" " + matrix[i][j]);
}
System.out.println();
}
}
private void printCharMatrix(char[][] matrix)
{
for (int i = 0; i <= pattern1.length; i++)
{
for (int j = 0; j < pattern2.length; j++)
{
System.out.print(" " + matrix[i][j]);
}
System.out.println();
}
}
void printCommonSequence(int i, int j)
{
if(i<1 || j<1)
return;
// now output the longest set of words.
if (res[i][j] == 'D')
{
printCommonSequence(i - 1, j - 1);
System.out.print(pattern1[i - 1] + " ");
} else if (res[i][j] == 'L')
{
printCommonSequence(i, j - 1);
} else if (res[i][j] == 'T')
{
printCommonSequence(i - 1, j);
}
}
}
It is still too long for my liking, and I don't exactly follow the complete steps of submitting the solution to the online judge. When working with Java, I tend to get a lot of timeout errors. That put me off so much that now I only try to solve the problem to my liking, and if I am satisfied with the algorithm, I can live without getting formal approval from the judge.
<code>
package uva;
public class Compromise
{
char[][] res;
int[][] dp;
static String[] pattern1;
static String[] pattern2;
public static void main(String[] args)
{
String string1 = "die einkommen der landwirte sind fuer die abgeordneten ein buch mit sieben siegeln um dem abzuhelfen muessen dringend"
+ " alle subventionsgesetze verbessert werden";
String string2 = "die steuern auf vermoegen und einkommen sollten nach meinung der abgeordneten nachdruecklich erhoben werden dazu muessen"
+ " die kontrollbefugnisse der finanzbehoerden dringend verbessert werden";
pattern1 = string1.split(" ");
pattern2 = string2.split(" ");
new Compromise().compromise(pattern1, pattern2);
}
private void compromise(String[] pattern1, String[] pattern2)
{
dp = new int[pattern1.length + 1][pattern2.length + 1];
res = new char[pattern1.length + 1][pattern2.length + 1];
for (int i = 1; i <= pattern1.length; i++)
dp[i][0] = 0;
for (int j = 0; j <= pattern2.length; j++)
dp[0][j] = 0;
// First write the solution for characters only.
for (int i = 1; i <= pattern1.length; i++)
for (int j = 1; j <= pattern2.length; j++)
{
if (pattern1[i - 1].equals(pattern2[j - 1]))
{
dp[i][j] = dp[i - 1][j - 1] + 1;
res[i][j] = 'D'; // from top left, means diagonal
} else if (dp[i - 1][j] >= dp[i][j - 1])
{
dp[i][j] = dp[i - 1][j];
res[i][j] = 'T'; // from top
} else
{
dp[i][j] = dp[i][j - 1];
res[i][j] = 'L'; // from left
}
}
System.out.println("Final matrix is: ");
printIntMatrix(dp);
System.out.println("Result is: ");
printCharMatrix(res);
printCommonSequence(pattern1.length, pattern2.length);
System.out.println("\nLength is "
+ dp[pattern1.length][pattern2.length]);
}
private void printIntMatrix(int[][] matrix)
{
for (int i = 0; i <= pattern1.length; i++)
{
for (int j = 0; j < pattern2.length; j++)
{
System.out.print(" " + matrix[i][j]);
}
System.out.println();
}
}
private void printCharMatrix(char[][] matrix)
{
for (int i = 0; i <= pattern1.length; i++)
{
for (int j = 0; j < pattern2.length; j++)
{
System.out.print(" " + matrix[i][j]);
}
System.out.println();
}
}
void printCommonSequence(int i, int j)
{
if(i<1 || j<1)
return;
// now output the longest set of words.
if (res[i][j] == 'D')
{
printCommonSequence(i - 1, j - 1);
System.out.print(pattern1[i - 1] + " ");
} else if (res[i][j] == 'L')
{
printCommonSequence(i, j - 1);
} else if (res[i][j] == 'T')
{
printCommonSequence(i - 1, j);
}
}
}
</code>