JS Longest Palindrome Substring (Manacher)
JavaScript resolve longest palindrome substring problem by Manacher algorithm.
by Tinytsunami
HTML
<div id="demo">
String = <input type="text" /> <button>Process</button>
<pre>waiting for you input something...</pre>
</div>
CSS
body {
color: #ffffff;
background: #20262e;
font-family: monospace, sans-serif;
}
#demo {
width: 400px;
padding: 5px;
}
#demo input {
color: #ffffff;
background: #20262e;
outline: none;
border: none;
border-bottom: 1px solid #ffffff;
}
#demo pre {
width: 400px;
height: 100px;
border: solid 1px #ffffff;
overflow-y: scroll;
}
#demo button {
color: #ffffff;
background: #20262e;
border: 1px solid #ffffff;
outline: none;
}
#demo button:hover {
color: #20262e;
background: #ffffff;
border: 1px solid #ffffff;
}
JavaScript
(function() {
/* get elements */
let root = document.getElementById("demo");
let inputNode = root.getElementsByTagName("input")[0];
let buttonNode = root.getElementsByTagName("button")[0];
let outputNode = root.getElementsByTagName("pre")[0];
/* evaluation time for functions */
let evaluationTime = function(f, callback) {
let start = Date.now();
let value = f();
callback.call(this, value, (Date.now() - start));
};
/* get LPS by exhaustive */
let main = function(text) {
let s = text; // change origin string
let i, j; // palindrome right, left index
let k = 0; // palindrome center
let p; // palindrome array
let m = 0; // protected range
s = `#${s.split('').join('#')}#`;
p = Array.from({length: s.length}, function() {return 0;});
// main process
for (i = 0; i < p.length; i++) {
j = 2 * k - i;
if (i + p[j] < m)
p[i] = p[j];
else {
p[i] = m - i;
while (s[i + p[i]] == s[i - p[i]]) {
p[i]++;
if (i + p[i] >= s.length || i - p[i] < 0)
break; // overflow
}
k = i;
m = k + p[k];
}
}
// get answer
let ans;
let ansLength, ansIndex;
let ansStart, ansEnd;
ansLength = Math.max.apply(this, p);
ansIndex = p.indexOf(ansLength);
ansStart = ansIndex - ansLength + 1;
ansEnd = ansIndex + ansLength;
ans = s.substring(ansStart, ansEnd).replace(/#/g, '');
return ans;
};
/* user input and process*/
buttonNode.onclick = function() {
evaluationTime(function() {
return main(inputNode.value);
}, function(LPS, time) {
if (LPS.length > 30)
LPS = `${LPS.substr(0, 30)}...`;
outputNode.innerHTML += `\nLPS = "${LPS}"\nTime = ${time}ms\n`;
outputNode.scrollTop = outputNode.scrollHeight;
});
};
})();