### Question:
StringEditDistance { public static BiCounter<Character, EdOp> operations(String first, String second) { int i, j; int[][] A; EditTable B; BiCounter<Character, EdOp> stats = new BiCounter<Character, EdOp>(); A = new int[2][second.length() + 1]; B = new EditTable(first.length() + 1, second.length() + 1); A[0][0] = 0; B.set(0, 0, EdOp.KEEP); for (j = 1; j <= second.length(); ++j) { A[0][j] = A[0][j - 1] + 1; B.set(0, j, EdOp.INSERT); } for (i = 1; i <= first.length(); ++i) { A[i % 2][0] = A[(i - 1) % 2][0] + 1; B.set(i, 0, EdOp.DELETE); for (j = 1; j <= second.length(); ++j) { if (first.charAt(i - 1) == second.charAt(j - 1)) { A[i % 2][j] = A[(i - 1) % 2][j - 1]; B.set(i, j, EdOp.KEEP); } else { A[i % 2][j] = min(A[(i - 1) % 2][j] + 1, A[i % 2][j - 1] + 1, A[(i - 1) % 2][j - 1] + 1); if (A[i % 2][j] == A[(i - 1) % 2][j] + 1) { B.set(i, j, EdOp.DELETE); } else if (A[i % 2][j] == A[i % 2][j - 1] + 1) { B.set(i, j, EdOp.INSERT); } else { B.set(i, j, EdOp.SUBSTITUTE); } } } } i = first.length(); j = second.length(); while (i > 0 && j > 0) { switch (B.get(i, j)) { case KEEP: stats.inc(first.charAt(i - 1), EdOp.KEEP); --i; --j; break; case DELETE: stats.inc(first.charAt(i - 1), EdOp.DELETE); --i; break; case INSERT: stats.inc(second.charAt(j - 1), EdOp.INSERT); --j; break; case SUBSTITUTE: stats.inc(first.charAt(i - 1), EdOp.SUBSTITUTE); --i; --j; break; } } while (i > 0) { stats.inc(first.charAt(i - 1), EdOp.DELETE); --i; } while (j > 0) { stats.inc(second.charAt(j - 1), EdOp.INSERT); --j; } return stats; }  static int indel(String first, String second); static int levenshtein(String first, String second); static int DL(String first, String second); static int distance(String first, String second, EditDistanceType type); static BiCounter<Character, EdOp> operations(String first, String second); static int[] alignment(String first, String second);  }### Answer:
@Test public void testOperations() { System.out.println("operations"); String first = "patata"; String second = "apta"; BiCounter<Character, EdOp> expResult = new BiCounter<Character, EdOp>(); expResult.add('a', EdOp.KEEP, 2); expResult.inc('t', EdOp.KEEP); expResult.inc('p', EdOp.DELETE); expResult.inc('t', EdOp.SUBSTITUTE); expResult.inc('a', EdOp.DELETE); BiCounter<Character, EdOp> result = StringEditDistance.operations(first, second); System.out.println(result); assertEquals(expResult, result); }