2015-11-12 23 views
9

文字列中で最も長い回文を見つけるために次の関数を書いた。それはうまく動作しますが、それは "正午"や "赤い"のような言葉のために動作しません。私の周りいじっからforループの最初の行を変更:文字列中の最長の回文文字列

var oddPal = centeredPalindrome(i, i); 

var oddPal = centeredPalindrome(i-1, i); 

をし、今では動作しますが、私は理由上明確ではありませんよ。私の直感は、あなたが奇妙な長さのパリンドロームをチェックしている場合、最初に余分なキャラクターが1つあることになります(私はそれをホワイトボードに出しました。私の推論で正しい軌道にいるのだろうか?

var longestPalindrome = function(string) { 

    var length = string.length; 
    var result = ""; 

    var centeredPalindrome = function(left, right) { 
    while (left >= 0 && right < length && string[left] === string[right]) { 
     //expand in each direction. 
     left--; 
     right++; 
    } 

    return string.slice(left + 1, right); 
    }; 

    for (var i = 0; i < length - 1; i++) { 
    var oddPal = centeredPalindrome(i, i); 
    var evenPal = centeredPalindrome(i, i); 

    if (oddPal.length > result.length) 
     result = oddPal; 
    if (evenPal.length > result.length) 
     result = evenPal; 
    } 

    return "the palindrome is: " + result + " and its length is: " + result.length; 
}; 

UPDATE:ポールの素晴らしいanswer後 、私はそれを明確にするため、両方の変数を変更することは理にかなって思う:

var oddPal = centeredPalindrome(i-1, i + 1); 
var evenPal = centeredPalindrome(i, i+1); 
+0

はい - それは最後に意味があります。もちろん、あなたは "中心"がオッズのために1の代わりに2になるので、EVEN回文のi + 1を行うでしょう。ありがとう! – devdropper87

+0

これは、上記の編集をより直観的にするかもしれないと思います。var oddPal = centeredPalindrome(i-1、i + 1); var evenPal = centeredPalindrome(i、i + 1); – devdropper87

+0

この問題の高速直線時間アルゴリズムが['Manacher's algorithm'](https://en.wikipedia.org/wiki/Longest_palindromic_substring)として知られています。 – Blastfurnace

答えて

4

あなたは後方にそれを持っている - あなたの出力ならば、あなたと「奇数」回文(あなたが実際に偶数長であることを見つけるでしょう。

最初の "o"(左と右)から始まる "正午"を想像してください。一致すると、両方を移動します - 今では、最初の "n"と2番目の "o"を比較しています。いいえ。しかし、この修正では、両方の "o"を比較してから、両方の "n"に移動します。 (var oddPal = centeredPalindrome(i-1, i);修正付き)

例:

var longestPalindrome = function(string) { 
 

 
    var length = string.length; 
 
    var result = ""; 
 

 
    var centeredPalindrome = function(left, right) { 
 
    while (left >= 0 && right < length && string[left] === string[right]) { 
 
     //expand in each direction. 
 
     left--; 
 
     right++; 
 
    } 
 

 
    return string.slice(left + 1, right); 
 
    }; 
 

 
    for (var i = 0; i < length - 1; i++) { 
 
    var oddPal = centeredPalindrome(i, i + 1); 
 

 
    var evenPal = centeredPalindrome(i, i); 
 

 
    if (oddPal.length > 1) 
 
     console.log("oddPal: " + oddPal); 
 
    if (evenPal.length > 1) 
 
     console.log("evenPal: " + evenPal); 
 

 
    if (oddPal.length > result.length) 
 
     result = oddPal; 
 
    if (evenPal.length > result.length) 
 
     result = evenPal; 
 
    } 
 
    return "the palindrome is: " + result + " and it's length is: " + result.length; 
 
}; 
 

 
longestPalindrome("nan noon is redder");

+0

私はこのコードがスペースをチェックするとは思わない。たとえば、 'longestPalindrome("レベルb "); の場合、長さが7の「レベル」として最長の回文を取得します。 – jmdeamer

+0

(ただし、私の読書の範囲外ですが)質問。間違いなく、問題のその部分を解決する独自の答えを追加することを検討してください。 –

0

最大の回文が先に発見された場合、これは最適となります。 見つかったら両方のループを終了します。

function isPalindrome(s) { 
     //var rev = s.replace(/\s/g,"").split('').reverse().join(''); //to remove space 
     var rev = s.split('').reverse().join(''); 
     return s == rev; 
    } 

    function longestPalind(s) { 
     var maxp_length = 0, 
     maxp = ''; 
     for (var i = 0; i < s.length; i++) { 
     var subs = s.substr(i, s.length); 
     if (subs.length <= maxp_length) break; //Stop Loop for smaller strings 
     for (var j = subs.length; j >= 0; j--) { 
      var sub_subs = subs.substr(0, j); 
      if (sub_subs.length <= maxp_length) break; // Stop loop for smaller strings 
      if (isPalindrome(sub_subs)) { 

       maxp_length = sub_subs.length; 
       maxp = sub_subs; 

      } 
     } 
     } 
     return maxp; 
    } 
関連する問題