2015-11-12 23 views
9

Ho scritto la seguente funzione per trovare il palindromo più lungo in una stringa. Funziona bene ma non funzionerà con parole come "mezzogiorno" o "rosso". I giocherellava intorno e cambiato la prima riga del ciclo for da:Palindrome più lungo in una stringa

var oddPal = centeredPalindrome(i, i); 

a

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

e ora funziona, ma io non sono chiare sul perché . La mia intuizione è che se stai controllando un palindromo di lunghezza dispari avrà all'inizio un personaggio in più (l'ho messo in lavagna e questa è la conclusione cui sono arrivato). Sono sulla buona strada con il mio ragionamento?

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: Dopo Paolo impressionante answer, penso che ha senso cambiare entrambe le variabili per la chiarezza:

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

SÌ - che ha finalmente senso. ovviamente si farebbe io + 1 per i palindromi EVEN perché il loro "centro" sarebbe 2 invece di 1 per le probabilità. Grazie! – devdropper87

+0

Penso che questo potrebbe essere più intuitivo, modificando anche sopra: var oddPal = centeredPalindrome (i-1, i + 1); var evenPal = centeredPalindrome (i, i + 1); – devdropper87

+0

Volevo solo sottolineare che esiste un algoritmo di tempo lineare veloce per questo problema noto come [algoritmo di Manacher] (https://en.wikipedia.org/wiki/Longest_palindromic_substring). – Blastfurnace

risposta

4

Hai all'indietro - se l'output dei palindromi "dispari" (con la vostra correzione) scoprirai che sono effettivamente di lunghezza pari.

Immagina "mezzogiorno", iniziando dalla prima "o" (sinistra e destra). Ciò corrisponde, quindi li sposti entrambi - ora stai confrontando la prima "n" alla seconda "o". Non buono. Ma con la correzione, si inizia a confrontare entrambi i "o" e quindi si passa a entrambi "n".

Esempio (con la var oddPal = centeredPalindrome(i-1, i); fix):

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

Non penso che questo codice controlli gli spazi. Quindi, se ad esempio hai eseguito 'longestPalindrome (" a livello b ");' si otterrebbe il palindromo più lungo come "livello" con una lunghezza di 7. – jmdeamer

+0

Vero, anche se fuori dal campo di applicazione (la mia lettura di) la domanda. Sicuramente considera di aggiungere la tua risposta che risolva quella parte del problema. –

0

Questo sarà ottimale se il più grande palindromo è trovato in precedenza. Una volta trovato, uscirà da entrambi i loop.

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; 
    } 
Problemi correlati