それでは、O(ND)アルゴリズムを実装しましょう。前のソースコードの「末尾2」のコメントの下に以下のコードを追加してください。2回に分けます。
1 <script type="text/javascript">
2 var V_INIT = 0;
3 var V_X = 1;
4 var V_Y = 2;
5
6 function getV_Status(v_minus, v_plus) {
7
8 if ((v_minus == undefined) && (v_plus == undefined)) { return V_INIT; }
9 if (v_minus == undefined) { return V_X; }
10 if (v_plus == undefined) { return V_Y; }
11
12 if (v_minus.x < v_plus.x) {
13 return V_X;
14 } else {
15 return V_Y;
16 }
17 }
18
19 function getEndPoint(str1, str2) {
20 var v = new Array(str1.length+str2.length+3);
21 var offset = str2.length + 1;
22
23 for (var d = 0; d <= str1.length+str2.length; d++) {
24 var k_max = (d <= str1.length) ? d : (str1.length - (d - str1.length));
25 var k_min = (d <= str2.length) ? d : (str2.length - (d - str2.length));
26
27 for (var k = -k_min; k <= k_max; k+=2) {
28 var index = offset + k;
29 var x;
30 var y;
31 var parent;
32
33 switch(getV_Status(v[index-1], v[index+1])) {
34 case V_INIT:
35 x = 0;
36 y = 0;
37 parent = {x:0, y:0, parent:null};
38 break;
39
40 case V_X:
41 x = v[index+1].x;
42 y = v[index+1].y + 1;
43 parent = v[index+1];
44 break;
45
46 case V_Y:
47 x = v[index-1].x + 1;
48 y = v[index-1].y;
49 parent = v[index-1];
50 break;
51
52 }
53
54 while (((x < str1.length) && (y < str2.length))
55 && (str1.charAt(x) == str2.charAt(y))) {
56 x++;
57 y++;
58 }
59
60 v[index] = {x:x, y:y, parent:parent};
61
62 if ((str1.length <= x) && (str2.length <= y)) {
63 return v[index];
64 }
65 }
66 }
67 }
68
69 function getDiffStringOND(str1, str2) {
70 var point = getEndPoint(str1, str2);
71 var diff_string = "";
72 while (point.parent != null) {
73 var parent = point.parent;
74 var diff_x = point.x - parent.x
75 var diff_y = point.y - parent.y
76 var same_len = Math.min(diff_x, diff_y);
77
78 for (var i = 0; i < same_len; i++) {
79 diff_string = str1.charAt(point.x-i-1) + diff_string;
80 }
81
82 if (diff_y < diff_x) {
83 diff_string = minus_ch(str1.charAt(parent.x)) + diff_string;
84 } else if (diff_x < diff_y) {
85 diff_string = plus_ch(str2.charAt(parent.y)) + diff_string;
86 }
87
88 point = parent;
89 }
90
91 return diff_string;
92 }
93
94 function execDiffOND() {
95 var text = getStringById('text');
96 var area = getStringById('area');
97 var diff_string = getDiffStringOND(text, area);
98 document.getElementById('diff').innerHTML = diff_string;
99 }
100 </script>
101 <input value="diff (O(ND))" type="button" onClick="execDiffOND()"></input><br><br>
これまで10回にわたって、さまざまなアルゴリズムを紹介してきました。普段当たり前のように使っている処理でも実にさまざまなやり方があり、パフォーマンスや実装のスマートさに違いが出て奥が深いと思われたことでしょう。この連載によってコンピュータ的な発想のトレーニングに役立つことができれば幸いです。
Copyright © ITmedia, Inc. All Rights Reserved.