算法大概描述就是,分别用两个字符串作为横坐标和纵坐标建一个矩阵,遇到横竖字符相同的时候把这点的值设成1,否则设成零,最后矩阵中最长的不为零的对角线就是最大子字串。
例如:
m | a | c | h | i | |
a | 0 | 1 | 0 | 0 | 0 |
b | 0 | 0 | 0 | 0 | 0 |
m | 1 | 0 | 0 | 0 | 0 |
a | 0 | 1 | 0 | 0 | 0 |
c | 0 | 0 | 1 | 0 | 0 |
这样有点问题:建完矩阵还要去找最长对角线,麻烦。
解决方案是:相等时不只把矩阵元素设为“1”,而是设成它左上角的元素值加一。
例如:
m | a | c | h | i | |
a | 0 | 1 | 0 | 0 | 0 |
b | 0 | 0 | 0 | 0 | 0 |
m | 1 | 0 | 0 | 0 | 0 |
a | 0 | 2 | 0 | 0 | 0 |
c | 0 | 0 | 3 | 0 | 0 |
所以矩阵建好后,找到矩阵中最大的元素就ok了。
<script src='jquery.js'></script> <meta charset='utf-8'/> <input id='s1' value='yanhuiabmac'/> <input id='s2' value='yanbchuimachi'/> <button onclick='calc()'>计算公共串</button> <table id='out' border=1></table> <table id='matrix' border=1></table> <script> function calc() { var s1 = $('#s1').val().split(''); var s2 = $('#s2').val().split(''); // . S 1 // S - - // 2 - - var matrix = []; // matrix[row][col] for (var i = 0; i < s2.length; ++i) { matrix[i] = []; for (var j = 0; j < s1.length; ++j) matrix[i][j] = (s1[j] == s2[i] ? 1 + (i != 0 && j != 0 ? matrix[i - 1][j - 1] : 0) : 0); } var res = []; for (var i in matrix) for (var j in matrix[i]) { var n = matrix[i][j]; if (typeof i != 'number') i = parseInt(i, 10); if (n) res.push([ s2.slice(i-n+1, i+1).join(''), n ]); } res.sort(); res = (function(s){ var d = []; $.each(s, function(i){ if(i==0 || s[i-1][0] != s[i][0]) d.push(s[i]); }); return d; })(res); res.sort(function(a,b){return b[1]-a[1];}); res.unshift(['*公共串*', '*长度*']); matrix.unshift([''].concat( (function(a){ var b = []; for (var i in a) b.push('*' + a[i] + '*'); return b; })(s1))); for (var i = 0; i < s2.length; ++i) matrix[1 + i].unshift('*' + s2[i] + '*'); for (var i = 1; i < matrix.length; ++i) for (var j = 1; j < matrix[0].length; ++j) if (!matrix[i][j]) matrix[i][j] = ''; var m2t = function (m) { var s = ''; for (var i in m) { s += '<tr>'; for (var j in m[i]) s += (function(c){ var p = 'td'; if (c.match(/\*.+\*/)) { c = c.replace(/\*(.+)\*/, '$1'); p = 'th'; } return '<' + p + '>' + c + '</' + p + '>'; })(new String(m[i][j])); s += '</tr>'; } return s; }; $('#matrix').html(m2t(matrix)); $('#out').html(m2t(res)); } </script>