package is2.lemmatizer;
import is2.parser.Parser;
import java.util.ArrayList;
public class StringEdit {
public static void main(String args[]) {
String s = new StringBuffer(args[0]).reverse().toString();
String t = new StringBuffer(args[1]).reverse().toString();
int d[][] = LD(s, t);
StringBuffer opersations = new StringBuffer();
searchPath(s, t, d, opersations, false);
Parser.out.println("resuylt " + " " + opersations);
}
//****************************
// Get minimum of three values
//****************************
static private int Minimum(int a, int b, int c) {
int mi;
mi = a;
if (b < mi) {
mi = b;
}
if (c < mi) {
mi = c;
}
return mi;
}
//*****************************
// Compute Levenshtein distance
//*****************************
static public int[][] LD(String s, String t) {
int n = s.length();
int m = t.length(); // length of t
// char s_i; // ith character of s
// char t_j; // jth character of t
int cost; // cost
// Step 1
int[][] d = new int[n + 1][m + 1];
if (n == 0) {
return d;
}
if (m == 0) {
return d;
}
// Step 2
for (int i = 0; i <= n; i++) {
d[i][0] = i;
}
for (int j = 0; j <= m; j++) {
d[0][j] = j;
}
// Step 3
for (int i = 1; i <= n; i++) {
int s_i = s.charAt(i - 1);
// Step 4
for (int j = 1; j <= m; j++) {
// t_j = t.charAt (j - 1);
// Step 5
if (s_i == t.charAt(j - 1)) {
cost = 0;
} else {
cost = 1;
}
// Step 6
d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
}
}
// Step 7
return d;
}
static String searchPath(String s, String t, int[][] d, StringBuffer operations, boolean debug) {
StringBuilder result = new StringBuilder(s);
int n = d.length;
int m = d[0].length;
int x = n - 1;
int y = m - 1;
boolean changed = false;
while (true) {
if (debug && changed) {
Parser.out.println("result " + new StringBuffer(result).reverse());
}
if (d[x][y] == 0) {
break;
}
if (y > 0 && x > 0 && d[x - 1][y - 1] < d[x][y]) {
if (debug) {
Parser.out.println("min d[x-1][y-1] " + d[x - 1][y - 1] + " d[x][y] " + d[x][y] + " rep " + s.charAt(x - 1) + " with " + t.charAt(y - 1) + " at " + (x - 1));
}
operations.append('R').append(Character.toString((char) ((int) x - 1))).append(s.charAt(x - 1)).append(t.charAt(y - 1));
if (debug) {
result.setCharAt(x - 1, t.charAt(y - 1));
}
y--;
x--;
changed = true;
continue;
}
if (y > 0 && d[x][y - 1] < d[x][y]) {
if (debug) {
Parser.out.println("min d[x][y-1] " + d[x][y - 1] + " d[x][y] " + d[x][y] + " ins " + t.charAt(y - 1) + " at " + (x));
}
operations.append('I').append(Character.toString((char) ((int) x))).append(t.charAt(y - 1));
if (debug) {
result.insert(x, t.charAt(y - 1));
}
y--;
changed = true;
continue;
}
if (x > 0 && d[x - 1][y] < d[x][y]) {
if (debug) {
Parser.out.println("min d[x-1][y] " + d[x - 1][y] + " d[x][y] " + d[x][y] + " del " + s.charAt(x - 1) + " at " + (x - 1));
}
operations.append('D').append(Character.toString((char) ((int) x - 1))).append(s.charAt(x - 1));
if (debug) {
result.deleteCharAt(x - 1);
}
x--;
changed = true;
continue;
}
changed = false;
if (x > 0 && y > 0 && d[x - 1][y - 1] == d[x][y]) {
x--;
y--;
continue;
}
if (x > 0 && d[x - 1][y] == d[x][y]) {
x--;
continue;
}
if (y > 0 && d[x][y - 1] == d[x][y]) {
y--;
continue;
}
}
if (debug) {
return result.reverse().toString();
} else {
return null;
}
}
public static String change(String s, String operations) {
StringBuffer result = new StringBuffer(s).reverse();
int pc = 0;
while (true) {
if (operations.length() <= pc) {
break;
}
char nextOperation = operations.charAt(pc);
pc++;
if (nextOperation == 'R') {
//pc++;
int xm1 = (char) operations.charAt(pc);
pc++;
char replace = operations.charAt(pc);
pc++;
char with = operations.charAt(pc);
//operations.append('R').append((char)x-1).append(s.charAt(x-1)).append(t.charAt(y-1));
// Parser.out.println(""+result+" xm1 "+xm1+" op "+operations);
if (result.length() <= xm1) {
return s;
}
if (result.charAt(xm1) == replace) {
result.setCharAt(xm1, with);
}
//if (debug) result.setCharAt(x-1, t.charAt(y-1));
pc++;
} else if (nextOperation == 'I') {
// if (debug) Parser.out.println("min d[x][y-1] "+d[x][y-1]+" d[x][y] "+d[x][y]+" ins "+t.charAt(y-1)+" at "+(x));
//operations.append('I').append((char)x).append(t.charAt(y-1));
//if (debug)result.insert(x, t.charAt(y-1));
//y--;
//changed =true;
//pc++;
int x = operations.charAt(pc);
pc++;
char in = operations.charAt(pc);
if (result.length() < x) {
return s;
}
result.insert(x, in);
pc++;
} else if (nextOperation == 'D') {
//pc++;
int xm1 = operations.charAt(pc);
if (result.length() <= xm1) {
return s;
}
result.deleteCharAt(xm1);
pc++;
// delete with
pc++;
// operations.append('D').append((char)x-1).append(s.charAt(x-1));
// if (debug)result.deleteCharAt(x-1);
}
}
return result.reverse().toString();
//else return null;
}
/**
* @param opers
* @param postion
* @return
*/
public static String get(ArrayList<String> opers, int position) {
for (String s : opers) {
int p = (int) s.charAt(1);
if (p == position) {
return s;
}
}
return "0";
}
/**
* @param form
* @param string
* @param c
* @return
*/
public static String changeSimple(String form, String operation, int c) {
if (operation.equals("0")) {
return form;
}
if (operation.charAt(0) == 'I') {
StringBuilder f = new StringBuilder(form);
if (f.length() <= c) {
// DB.println("fail insert ");
return form;
}
f.insert(c + 1, operation.charAt(1));
return f.toString();
}
if (operation.charAt(0) == 'R') {
StringBuilder f = new StringBuilder(form);
// if (f.length()<=c) f.append(' ');
if (f.length() <= c) {
// DB.println("fail replace ");
return form;
}
f.setCharAt(c, operation.charAt(2));
return f.toString();
}
if (operation.charAt(0) == 'D') {
StringBuilder f = new StringBuilder(form);
f.delete(c, c + 1);//.append(' ');
return f.toString();
}
return form;
}
/**
* @param string
* @return
*/
public static String simple(String o) {
StringBuilder s = new StringBuilder(o);
s.delete(1, 2);
return s.toString();
}
}