ejemplos - Palíndromo check in Javascript
javascript html (30)
25 veces más rápido que la respuesta estándar
function isPalindrome(s,i) {
return (i=i||0)<0||i>=s.length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
}
usar como:
isPalindrome(''racecar'');
como define el "yo" mismo
Fiddle: http://jsfiddle.net/namcx0yf/9/
Esto es ~ 25 veces más rápido que la respuesta estándar a continuación.
function checkPalindrome(str) {
return str == str.split('''').reverse().join('''');
}
Fiddle: http://jsfiddle.net/t0zfjfab/2/
Ver consola para resultados de rendimiento.
Aunque la solución es difícil de leer y mantener, recomendaría entenderla para demostrar que no se ramifican con recursión y cambio de bit para impresionar a su próximo entrevistador.
explicado
El || y && se usan para flujo de control como "if" "else". Si queda algo de || es cierto, simplemente sale con verdadero. Si algo es falso a la izquierda de || debe continuar Si algo sale de && es falso, sale como falso, si algo queda de un && es verdadero, debe continuar. Esto se considera "no ramificado", ya que no necesita interupciones if-else, sino que simplemente se evalúa.
1. Usé un inicializador que no requiere que "i" se defina como un argumento. Asigna "i" a sí mismo si está definido; de lo contrario, inicializa a 0. Siempre es falso, por lo que la siguiente O condición siempre se evalúa.
(i = i || 0) < 0
2. Comprueba si "i" fue a mitad de camino, pero se salta al chequear el char impar medio. El bit desplazado aquí es como división por 2 pero a la división vecina más baja por 2 resultado. Si es verdadero, asume palindrome porque ya está hecho. Si es falso evalúa la siguiente condición OR.
i >= s.length >> 1
3. Se compara desde el principio char y final char según "i" eventualmente para encontrarse como vecinos o vecinos a medio char. If false sale y asume NOT palindrome. Si es verdadero continúa en la siguiente condición AND.
s[i] == s[s.length-1-i]
4. Se llama de nuevo para la recursión pasando la cadena original como "s". Dado que "i" se define con seguridad en este punto, se incrementa previamente para continuar comprobando la posición de la cadena. Devuelve el valor booleano que indica si es palindrome.
isPalindrome(s,++i)
PERO...
Un simple bucle for es todavía el doble de rápido que mi respuesta elegante ( también conocido como principio KISS )
function fastestIsPalindrome(str) {
var len = Math.floor(str.length / 2);
for (var i = 0; i < len; i++)
if (str[i] !== str[str.length - i - 1])
return false;
return true;
}
Tengo lo siguiente:
function checkPalindrom(palindrom)
{
for( var i = palindrom.length; i > 0; i-- )
{
if( palindrom[i] = palindrom.charAt(palindrom.length)-1 )
{
document.write(''the word is palindrome.'');
}else{
document.write(''the word is not palindrome!'');
}
}
}
checkPalindrom(''wordthatwillbechecked'');
¿Qué pasa con mi código? Quiero verificar si la palabra es palindrome.
CÓDIGO MÁS CORTO (31 caracteres) (ES6):
p=s=>s==[...s].reverse().join``
p(''racecar''); //true
¿Qué tal esto, usando una simple bandera
function checkPalindrom(str){
var flag = true;
for( var i = 0; i <= str.length-1; i++){
if( str[i] !== str[str.length - i-1]){
flag = false;
}
}
if(flag == false){
console.log(''the word is not a palindrome!'');
}
else{
console.log(''the word is a palindrome!'');
}
}
checkPalindrom(''abcdcba'');
(JavaScript) Al usar regexp, se comprueba si hay palíndromo alfanumérico y se descarta el espacio y la puntuación.
function palindrome(str) {
str = str.match(/[A-Za-z0-9]/gi).join("").toLowerCase();
// (/[A-Za-z0-9]/gi) above makes str alphanumeric
for(var i = 0; i < Math.floor(str.length/2); i++) { //only need to run for half the string length
if(str.charAt(i) !== str.charAt(str.length-i-1)) { // uses !== to compare characters one-by-one from the beginning and end
return "Try again.";
}
}
return "Palindrome!";
}
palindrome("A man, a plan, a canal. Panama.");
//palindrome("4_2 (: /-/ :) 2-4"); // This solution would also work on something like this.
Al menos tres cosas:
Está intentando probar la igualdad con
=
, que se usa para establecer. Debe probar con==
o===
. (Probablemente este último, si no tiene una razón para el primero).Estás informando resultados después de verificar cada personaje. Pero no sabes los resultados hasta que hayas revisado suficientes caracteres.
Vuelva a verificar cada par de caracteres, ya que en realidad solo necesita verificar si, por ejemplo,
first === last
y no también silast === first
.
Aquí hay una solución que funciona incluso si la cadena contiene caracteres no alfanuméricos.
function isPalindrome(str) {
str = str.toLowerCase().replace(//W+|_/g, '''');
return str == str.split('''').reverse().join('''');
}
Como una función recursiva mucho más clara: http://jsfiddle.net/dmz2x117/
function isPalindrome(letters) {
var characters = letters.split(''''),
firstLetter = characters.shift(),
lastLetter = characters.pop();
if (firstLetter !== lastLetter) {
return false;
}
if (characters.length < 2) {
return true;
}
return isPalindrome(characters.join(''''));
}
Compartiendo mi variante rápida que también admite espacios
function isPalindrom(str) {
var ia = 0;
var ib = str.length - 1;
do {
if (str[ia] === str[ib]) continue;
// if spaces skip & retry
if (str[ia] === '' '' && ib++) continue;
if (str[ib] === '' '' && ia--) continue;
return false;
} while (++ia < --ib);
return true;
}
var palindrom="never odd or even";
var res = isPalindrom(palindrom);
document.getElementById(''check'').innerHTML =''"''+ palindrom + ''"''+" checked to be :" +res;
<span id="check" />
Encontré esto en un sitio de entrevistas:
Escribe una función eficiente que verifique si cualquier permutación de una cadena de entrada es un palíndromo. Puedes ignorar la puntuación, solo nos importan los personajes.
Jugando con eso, se me ocurrió esta fea pieza de código :)
function checkIfPalindrome(text) {
var found = {};
var foundOne = 0;
text = text.replace(/[^a-z0-9]/gi, '''').toLowerCase();
for (var i = 0; i < text.length; i++) {
if (found[text[i]]) {
found[text[i]]++;
} else {
found[text[i]] = 1;
}
}
for (var x in found) {
if (found[x] === 1) {
foundOne++;
if (foundOne > 1) {
return false;
}
}
}
for (var x in found) {
if (found[x] > 2 && found[x] % 2 && foundOne) {
return false;
}
}
return true;
}
Solo dejándolo aquí para la posteridad.
Escribir el código para verificar los palíndromos siguiendo las mejores prácticas de JavaScript:
(function(){
''use strict'';
var testStringOne = "Madam";
var testStringTwo = "testing";
var testNull = null;
var testUndefined;
console.log(checkIfPalindrome(testStringOne));
console.log(checkIfPalindrome(testStringTwo));
console.log(checkIfPalindrome(testNull));
console.log(checkIfPalindrome(testUndefined));
function checkIfPalindrome(testStringOne){
if(!testStringOne){
return false;
}
var testArrayOne = testStringOne.toLowerCase().split("");
testArrayOne.reverse();
if(testArrayOne.toString() == testStringOne.toLowerCase().split("").toString()){
return true;
}else{
return false;
}
}
})();
Esto evita la expresión regular mientras que también se ocupa de cadenas que tienen espacios y mayúsculas ...
function isPalindrome(str) {
str = str.split("");
var str2 = str.filter(function(x){
if(x !== '' '' && x !== '','') {
return x;
}
});
return console.log(str2.join('''').toLowerCase()) == console.log(str2.reverse().join('''').toLowerCase());
};
isPalindrome("A car, a man, a maraca"); //true
Esto funcionó para mí.
var number = 8008
number = number + "";
numberreverse = number.split("").reverse().join('''');
console.log ("The number if reversed is: " +numberreverse);
if (number == numberreverse)
console.log("Yes, this is a palindrome");
else
console.log("Nope! It isnt a palindrome");
He agregado algunas más a las funciones anteriores, para comprobar cadenas como, "Ve a colgar un salami, soy un cerdo de lasaña".
function checkPalindrom(str) {
var str = str.replace(/[^a-zA-Z0-9]+/gi, '''').toLowerCase();
return str == str.split('''').reverse().join('''');
}
Gracias
La lógica aquí no es del todo correcta, debe verificar cada letra para determinar si la palabra es un palíndromo. Actualmente, imprimes varias veces. ¿Qué tal hacer algo como esto?
function checkPalindrome(word) {
var l = word.length;
for (var i = 0; i < l / 2; i++) {
if (word.charAt(i) !== word.charAt(l - 1 - i)) {
return false;
}
}
return true;
}
if (checkPalindrome("1122332211")) {
document.write("The word is a palindrome");
} else {
document.write("The word is NOT a palindrome");
}
Que debería imprimir que ES de hecho un palíndromo.
Lo más importante que debe hacer cuando resuelve una prueba técnica es No utilizar métodos de acceso directo : ¡ quieren ver cómo piensa de forma algorítmica! No es su uso de métodos.
Aquí hay uno que se me ocurrió (45 minutos después de que volé la prueba). Sin embargo, hay un par de optimizaciones por hacer. Al escribir cualquier algoritmo, es mejor suponer que es false
y alterar la lógica si parece ser true
.
isPalindrome()
:
Básicamente, para hacer que esto se ejecute en complejidad O (N) (lineal), debe tener 2 iteradores cuyos vectores apuntan el uno hacia el otro. Es decir, un iterador que comienza al principio y otro que comienza al final, cada uno viajando hacia adentro. Podría hacer que los iteradores recorrieran toda la matriz y usar una condición para break
/ return
una vez que se encuentren en el medio, pero puede ahorrar algo de trabajo para dar a cada iterador una longitud media por defecto.
for
bucles parece forzar el uso de más controles, por lo que utilicé bucles while, con los que me siento menos cómodo.
Aquí está el código:
/**
* TODO: If func counts out, let it return 0
* * Assume !isPalindrome (invert logic)
*/
function isPalindrome(S){
var s = S
, len = s.length
, mid = len/2;
, i = 0, j = len-1;
while(i<mid){
var l = s.charAt(i);
while(j>=mid){
var r = s.charAt(j);
if(l === r){
console.log(''@while *'', i, l, ''...'', j, r);
--j;
break;
}
console.log(''@while !'', i, l, ''...'', j, r);
return 0;
}
++i;
}
return 1;
}
var nooe = solution(''neveroddoreven''); // even char length
var kayak = solution(''kayak''); // odd char length
var kayaks = solution(''kayaks'');
console.log(''@isPalindrome'', nooe, kayak, kayaks);
Observe que si los bucles cuentan, devuelve true
. Toda la lógica debe invertirse para que de manera predeterminada devuelva false
. También utilicé un método abreviado String.prototype.charAt(n)
, pero me sentí bien con esto, ya que cada idioma admite de forma nativa este método.
Método Recursivo:
var low;
var high;
var A = "abcdcba";
function palindrome(A , low, high){
A = A.split('''');
if((low > high) || (low == high)){
return true;
}
if(A[low] === A[high]){
A = A.join('''');
low = low + 1;
high = high - 1;
return palindrome(A , low, high);
}
else{
return "not a palindrome";
}
}
palindrome(A, 0, A.length-1);
Me funciona
function palindrome(str) {
/* remove special characters, spaces and make lowercase*/
var removeChar = str.replace(/[^A-Z0-9]/ig, "").toLowerCase();
/* reverse removeChar for comparison*/
var checkPalindrome = removeChar.split('''').reverse().join('''');
/* Check to see if str is a Palindrome*/
return (removeChar === checkPalindrome);
}
Me pregunto por qué nadie sugirió esto:
ES6:
// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
isPalindrom = (str = "") => {
if (str[0] === str[str.length - 1]) {
return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
}
return false;
}
alert(["aba", "acb", "aa", "abba", "s"].map((e, i) => isPalindrom(e)).join())
ES5:
// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
function isPalindrom(str) => {
var str = typeof str !== "string" ? "" : str;
if (str[0] === str[str.length - 1]) {
return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
}
return false;
}
alert(["aba", "acb", "aa", "abba", "s"].map(function (e, i) {
return isPalindrom(e);
}).join());
Pasa por los caracteres de cadena tanto hacia adelante (i) como hacia atrás (j) usando un ciclo for. Si en algún momento el personaje de str[i]
no es igual a str[j]
, entonces no es un palíndromo. Si hacemos un bucle con éxito a través de la cadena, entonces es un palíndromo.
function isPalindrome(str) {
var valid = true;
for(var i = 0, j = str.length - 1; i < str.length; i++, j--) {
if (str[i] !== str[j]) valid = false; break;
}
return valid;
}
Pensé que compartiría mi propia solución:
function palindrome(string){
var reverseString = '''';
for(var k in string){
reverseString += string[(string.length - k) - 1];
}
if(string === reverseString){
console.log(''Hey there palindrome'');
}else{
console.log(''You are not a palindrome'');
}
}
palindrome(''ana'');
Hope ayudará a alguien.
Pensé que compartiría mi solución usando Array.prototype.filter (). filter () filtra la matriz según los valores booleanos que devuelve la función.
var inputArray=["","a","ab","aba","abab","ababa"]
var outputArray=inputArray.filter(function isPalindrome(x){
if (x.length<2) return true;
var y=x.split("").reverse().join("");
return x==y;
})
console.log(outputArray);
Primer problema
= es asignar == es comparar
Segundo problema, tu lógica aquí está mal
palindrom.charAt(palindrom.length)-1
Estás restando uno de la charAt y no la longitud.
Tercer problema, todavía estará mal, ya que no estás reduciendo la longitud en i.
Tal vez sugeriré probablemente una mejor solución:
function checkPalindrom(str) {
return str == str.split('''').reverse().join('''');
}
Usando recursión:
function isPalindromeRecursive(str) {
const isLessThan2 = str.length < 2;
const firstAndLastEqual = str.slice(0, 1) === str.slice(-1);
return !isLessThan2 && firstAndLastEqual
? isPalindromeRecursive(str.slice(1, -1))
: isLessThan2;
}
`
function checkPalindrome (str) {
var str = str.toLowerCase();
var original = str.split('' '').join('''');
var reversed = original.split('' '').reverse().join('''');
return (original === reversed);
}
`
function checkPalindrom(palindrom)
{
var flag = true;
var j = 0;
for( var i = palindrom.length-1; i > palindrom.length / 2; i-- )
{
if( palindrom[i] != palindrom[j] )
{
flag = false;
break; // why this? It''ll exit the loop at once when there is a mismatch.
}
j++;
}
if( flag ) {
document.write(''the word is palindrome.'');
}
else {
document.write(''the word is not palindrome.'');
}
}
checkPalindrom(''wordthatwillbechecked'');
¿Por qué estoy imprimiendo el resultado fuera del ciclo? De lo contrario, para cada coincidencia de la palabra, se imprimirá "is or not pallindrome" en lugar de verificar toda la palabra.
EDITAR: actualizado con cambios y una solución sugerida por Basemm.
function checkPalindrom(palindrom)
{
palindrom= palindrom.toLowerCase();
var flag = true;
var j;
j = (palindrom.length) -1 ;
//console.log(j);
var cnt = j / 2;
//console.log(cnt);
for( i = 0; i < cnt+1 ; i++,j-- )
{
console.log("J is => "+j);
console.log(palindrom[i] + "<==>" + palindrom[j]);
if( palindrom[i] != palindrom[j] )
{
flag = false;
break;
}
}
if( flag ) {
console.log(''the word is palindrome.'');
}
else {
console.log(''the word is not palindrome.'');
}
}
checkPalindrom(''Avid diva'');
function myPolidrome(polidrome){
var string=polidrome.split('''').join('','');
for(var i=0;i<string.length;i++){
if(string.length==1){
console.log("is polidrome");
}else if(string[i]!=string.charAt(string.length-1)){
console.log("is not polidrome");
break;
}else{
return myPolidrome(polidrome.substring(1,polidrome.length-1));
}
}
}
myPolidrome("asasdsdsa");
function palindromCheck(str) {
var palinArr, i,
palindrom = [],
palinArr = str.split(/[/s!.?,;:''"-()]/ig);
for (i = 0; i < palinArr.length; i++) {
if (palinArr[i].toLowerCase() === palinArr[i].split('''').reverse().join('''').toLowerCase() &&
palinArr[i] !== '''') {
palindrom.push(palinArr[i]);
}
}
return palindrom.join('', '');
}
console.log(palindromCheck(''There is a man, his name! was Bob.'')); //a, Bob
Encuentra y mayúscula a minúscula. Dividir cadena en matriz, no sé por qué quedan algunos espacios en blanco, pero quería capturar y letras sueltas.
-
=
enpalindrom[i] = palindrom.charAt(palindrom.length)-1
debe ser==
o===
-
palindrom.charAt(palindrom.length)-1
debe serpalindrom.charAt(palindrom.length - i)