/* * Problem : https://www.techiedelight.com/shortest-common-supersequence-introduction-scs-length/ */ import java.util.HashMap; import java.util.Map; class ShortestSupersequenceDP { private static void checkInputs(String X, String Y) { if (X == null || Y == null) { throw new IllegalArgumentException(); } } private static int recursion(String X, String Y, int m, int n) { if (m == 0 || n == 0) { return m + n; } if (X.charAt(m - 1) == Y.charAt(n - 1)) { return 1 + recursion(X, Y, m - 1, n -1); } return Math.min(recursion(X, Y, m - 1, n) + 1, recursion(X, Y, m, n -1) + 1); } public static int recursion(String X, String Y) { checkInputs(X, Y); return recursion(X, Y, X.length(), Y.length()); } private static int topDown(String X, String Y, int m, int n, Map<String, Integer> lookup) { if (m == 0 || n == 0) { return m + n; } String key = m + "|" + n; if (!lookup.containsKey(key)) { int length = 0; if (X.charAt(m - 1) == Y.charAt(n - 1)) { length = topDown(X, Y, m - 1, n - 1, lookup) + 1; } else { length = Math.min(1 + topDown(X, Y, m - 1, n, lookup), 1 + topDown(X, Y, m, n - 1, lookup)); } lookup.put(key, length); } return lookup.get(key); } public static int topDown(String X, String Y) { checkInputs(X, Y); Map<String, Integer> lookup = new HashMap<>(); return topDown(X, Y, X.length(), Y.length(), lookup); } private static int[][] getSCSTable(String X, String Y) { int m = X.length(); int n = Y.length(); int[][] table = new int[m + 1][n + 1]; for (int i = 0; i <= m; ++i) { for (int j = 0; j <= n; ++j) { int value = 0; if (i == 0) { value = j; } else if (j == 0) { value = i; } else if (X.charAt(i -1) == Y.charAt(j - 1)) { value = 1 + table[i - 1][j - 1]; } else { value = Math.min(1 + table[i - 1][j], 1 + table[i][j - 1]); } table[i][j] = value; } } return table; } public static int bottomUp(String X, String Y) { checkInputs(X, Y); int[][] table = getSCSTable(X, Y); return table[X.length()][Y.length()]; } } class Driver { public static void main(String[] args) { int lengthX = 10; int lengthY= 5; String X = RandomString.nextString(lengthX, RandomString.GENOME); String Y = RandomString.nextString(lengthY, RandomString.GENOME); System.out.println("X : " + X); System.out.println("Y : " + Y); System.out.println("Shortest supersequence length:"); System.out.println("Using recursion : " + ShortestSupersequenceDP.recursion(X, Y)); System.out.println("Using top down : " + ShortestSupersequenceDP.topDown(X, Y)); System.out.println("Using bottom up : " + ShortestSupersequenceDP.bottomUp(X, Y)); } }