1
+ import javax .rmi .CORBA .Util ;
2
+ import java .lang .reflect .Array ;
3
+ import java .util .*;
4
+ import java .util .Arrays ;
5
+
6
+
7
+ import static java .lang .Integer .max ;
8
+ import static java .lang .Integer .toBinaryString ;
9
+ import static java .lang .Math .abs ;
10
+ import static java .lang .Math .min ;
11
+
12
+ public class EditDistance implements EditDistanceInterface {
13
+
14
+ int c_i , c_d , c_r ;
15
+ int n , m ;
16
+ static int MAX = Integer .MAX_VALUE ;
17
+ static int UNDEF = -1 ;
18
+
19
+ public EditDistance (int c_i , int c_d , int c_r ) {
20
+ this .c_i = c_i ;
21
+ this .c_d = c_d ;
22
+ this .c_r = c_r ;
23
+ }
24
+
25
+ public int [][] getEditDistanceDP (String s1 , String s2 ) {
26
+
27
+ int n = s1 .length ();
28
+ int m = s2 .length ();
29
+
30
+ int [][] d = new int [n + 1 ][m + 1 ];
31
+
32
+ int factor_if_equal ;
33
+
34
+ //compute d_0_j and d_i_0
35
+ for (int i = 0 ; i < n + 1 ; i ++)
36
+ d [i ][0 ] = i * this .c_d ;
37
+ for (int j = 0 ; j < m + 1 ; j ++)
38
+ d [0 ][j ] = j * this .c_i ;
39
+
40
+ //compute the other values according to the lines
41
+ for (int i = 1 ; i < n + 1 ; i ++) {
42
+ for (int j = 1 ; j < m + 1 ; j ++) {
43
+
44
+
45
+ if (s1 .charAt (i - 1 ) == s2 .charAt (j - 1 ))
46
+ factor_if_equal = d [i - 1 ][j - 1 ];
47
+ else
48
+ factor_if_equal = d [i - 1 ][j - 1 ] + this .c_r ;
49
+ d [i ][j ] = min (min (factor_if_equal , d [i - 1 ][j ] + this .c_d ), d [i ][j - 1 ] + this .c_i );
50
+
51
+ }
52
+ }
53
+
54
+ return d ;
55
+ }
56
+
57
+
58
+ public List <String > getMinimalEditSequence (String s1 , String s2 ) {
59
+ HashMap <Integer , Integer > d = new HashMap ();
60
+ HashMap <Integer , String > op = new HashMap ();
61
+ int [] aux_value = new int [3 ];
62
+ String [] aux_string = new String [3 ];
63
+ int X ;
64
+ int arg ;
65
+ int bound ;
66
+ LinkedList <String > ls = new LinkedList <>();
67
+
68
+ int n = s1 .length ();
69
+ int m = s2 .length ();
70
+ this .n = n ;
71
+ this .m = m ;
72
+
73
+
74
+ X = 1 ; // upper bound
75
+ while (true ) {
76
+ bound = abs (n - m ) + X ;
77
+
78
+ d .clear ();
79
+
80
+ op .clear ();
81
+
82
+
83
+ //compute d_0_j and d_i_0
84
+ for (int i = 0 ; i < n + 1 ; i ++) {
85
+ d .put (cantor (i , 0 ), i * this .c_d );
86
+ op .put (cantor (i , 0 ), "delete(" + (i - 1 ) + ")" );
87
+
88
+ }
89
+ for (int j = 0 ; j < m + 1 ; j ++) {
90
+ d .put (cantor (0 , j ), j * this .c_i );
91
+ }
92
+ op .put (cantor (0 , 0 ), "nothing" );
93
+ for (int j = 1 ; j < m + 1 ; j ++) {
94
+ op .put (cantor (0 , j ), "insert(" + (j - 1 ) + "," + s2 .charAt (j - 1 ) + ")" );
95
+ }
96
+
97
+
98
+ //compute the other values according to the lines
99
+ for (int i = 1 ; i < n + 1 ; i ++) {
100
+
101
+ for (int j = max (1 , i - bound ); j <= min (m , i + bound ); j ++) {
102
+
103
+
104
+ if (i == j - bound )
105
+ aux_value [0 ] = Integer .MAX_VALUE ;
106
+ else {
107
+ aux_value [0 ] = d .get (cantor (i - 1 , j )) + this .c_d ;
108
+ aux_string [0 ] = "delete(" + (i - 1 ) + ")" ;
109
+ }
110
+ if (j == i - bound )
111
+ aux_value [1 ] = Integer .MAX_VALUE ; // we do not care about value outside of the diagonal, so we set them to infinity to make sure they're not chosen
112
+ else {
113
+ aux_value [1 ] = d .get (cantor (i , j - 1 )) + this .c_i ;
114
+ aux_string [1 ] = "insert(" + (j - 1 ) + "," + s2 .charAt (j - 1 ) + ")" ;
115
+ }
116
+ if (s1 .charAt (i - 1 ) == s2 .charAt (j - 1 )) {
117
+ if ((j == i - bound ) || (i == j - bound ))
118
+ aux_value [2 ] = Integer .MAX_VALUE ;
119
+ else {
120
+ aux_value [2 ] = d .get (cantor (i - 1 , j - 1 ));
121
+ aux_string [2 ] = "nothing" ;
122
+ }
123
+
124
+ }
125
+ else {
126
+ if ((j == i - bound ) || (i == j - bound ))
127
+ aux_value [2 ] = Integer .MAX_VALUE ;
128
+ else {
129
+ aux_value [2 ] = d .get (cantor (i - 1 , j - 1 )) + this .c_r ;
130
+ aux_string [2 ] = "replace(" + (i - 1 ) + "," + s2 .charAt (j - 1 ) + ")" ;
131
+ }
132
+
133
+ }
134
+
135
+
136
+ arg = argmin (aux_value );
137
+ d .put (cantor (i , j ), aux_value [arg ]);
138
+ op .put (cantor (i , j ), aux_string [arg ]);
139
+
140
+
141
+ }
142
+ }
143
+
144
+
145
+
146
+ if (X * (this .c_i + this .c_d ) >= d .get (cantor (n , m )))
147
+ break ;
148
+ else
149
+ X *= 2 ;
150
+
151
+ }
152
+
153
+
154
+ // read op in reverse to find the sequence we're looking for
155
+
156
+ Stack stack = new Stack (); //we need to read the insert instruction in the reverse order compared to the delete instructions
157
+ int i = n ;
158
+ int j = m ;
159
+ while (i >= 0 && j >= 0 ) {
160
+
161
+ char first_letter = op .get (cantor (i , j )).charAt (0 );
162
+ if (first_letter == "n" .toCharArray ()[0 ]){
163
+ i --;
164
+ j --;
165
+ }
166
+ if (first_letter == "d" .toCharArray ()[0 ]) {
167
+ ls .add (op .get (cantor (i , j )));
168
+ i --;
169
+
170
+ }
171
+ if (first_letter == "i" .toCharArray ()[0 ]) {
172
+ stack .push (op .get (cantor (i , j )));
173
+ j --;
174
+ }
175
+ if (first_letter == "r" .toCharArray ()[0 ]){
176
+ ls .add (op .get (cantor (i , j )));
177
+ i --;
178
+ j --;
179
+ }
180
+
181
+ }
182
+
183
+ while (! stack .empty ())
184
+ ls .add ((String ) stack .pop ()); //we need to read the insert instruction in the reverse order compared to the delete instructions
185
+
186
+ return ls ;
187
+ }
188
+
189
+ public int argmin (int [] arr ) {
190
+ int n = arr .length ;
191
+ int res = 0 ;
192
+
193
+ for (int i = 1 ; i < n ; i ++) {
194
+ if (arr [i ] < arr [res ])
195
+ res = i ;
196
+ }
197
+
198
+
199
+ return res ;
200
+
201
+ }
202
+
203
+ public int cantor (int i , int j ){
204
+ return i * (this .m + 1 ) + j ;
205
+ }
206
+
207
+
208
+ }
209
+ // }
210
+ // if (c_r == 6) {
211
+ // ls.add("delete(1)");
212
+ // ls.add("delete(1)");
213
+ // ls.add("insert(2,c)");
214
+ // ls.add("insert(3,b)");
215
+ // }
216
+ // else {
217
+ // ls.add("replace(1,d)");
218
+ // ls.add("replace(3,b)");
219
+ // }
220
+ // return ls;
221
+ // /* Code block to be removed ends. */
222
+ // }
223
+
224
+ //
225
+ // for (int i=0; i<n+1; i++) {
226
+ // for (int j = 0; j < m + 1; j++) {
227
+ // System.out.print(op[i][j]);
228
+ // }
229
+ // System.out.println("");
230
+ // }
0 commit comments