verificar una saber recursividad para palindromo palabra determinar cadena algoritmo string language-agnostic

string - una - verificar palindromo python



¿Cómo verificar si la cadena dada es palíndromo? (30)

C ++

std::string a = "god"; std::string b = "lol"; std::cout << (std::string(a.rbegin(), a.rend()) == a) << " " << (std::string(b.rbegin(), b.rend()) == b);

Intento

function ispalin { [ "$( echo -n $1 | tac -rs . )" = "$1" ]; } echo "$(ispalin god && echo yes || echo no), $(ispalin lol && echo yes || echo no)"

Gnu Awk

/* obvious solution */ function ispalin(cand, i) { for(i=0; i<length(cand)/2; i++) if(substr(cand, length(cand)-i, 1) != substr(cand, i+1, 1)) return 0; return 1; } /* not so obvious solution. cough cough */ { orig = $0; while($0) { stuff = stuff gensub(/^.*(.)$/, "//1", 1); $0 = gensub(/^(.*).$/, "//1", 1); } print (stuff == orig); }

Haskell

Un poco de muerte cerebral haciéndolo en Haskell

ispalin :: [Char] -> Bool ispalin a = a == (let xi (y:my) = (xi my) ++ [y]; xi [] = [] in /x -> xi x) a

Inglés simple

"Just reverse the string and if it is the same as before, it''s a palindrome"

Definición:

Un palíndromo es una palabra, frase, número u otra secuencia de unidades que tiene la propiedad de leer el mismo en cualquier dirección.

¿Cómo verificar si la cadena dada es un palíndromo?

Esta fue una de las FAIQ [Preguntas Frecuentes de la Entrevista] hace un tiempo, pero que usa principalmente C.

Buscando soluciones en todos los idiomas posibles.


Rubí:

class String def is_palindrome? letters_only = gsub(//W/,'''').downcase letters_only == letters_only.reverse end end puts ''abc''.is_palindrome? # => false puts ''aba''.is_palindrome? # => true puts "Madam, I''m Adam.".is_palindrome? # => true


Algoritmo in situ C # . Cualquier preprocesamiento, como la insensibilidad a mayúsculas y minúsculas o la eliminación de espacios en blanco y signos de puntuación, debe realizarse antes de pasar a esta función.

boolean IsPalindrome(string s) { for (int i = 0; i < s.Length / 2; i++) { if (s[i] != s[s.Length - 1 - i]) return false; } return true; }

Editar: eliminó innecesariamente " +1 " en la condición de ciclo y gastó la comparación guardada al eliminar la comparación de Longitud redundante. Gracias a los comentaristas!


Aquí está mi solución en c #

static bool isPalindrome(string s) { string allowedChars = "abcdefghijklmnopqrstuvwxyz"+ "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string compareString = String.Empty; string rev = string.Empty; for (int i = 0; i <= s.Length - 1; i++) { char c = s[i]; if (allowedChars.IndexOf(c) > -1) { compareString += c; } } for (int i = compareString.Length - 1; i >= 0; i--) { char c = compareString[i]; rev += c; } return rev.Equals(compareString, StringComparison.CurrentCultureIgnoreCase); }


Aquí está mi solución, sin usar un strrev. Escrito en C #, pero funcionará en cualquier idioma que tenga una función de longitud de cuerda.

private static bool Pal(string s) { for (int i = 0; i < s.Length; i++) { if (s[i] != s[s.Length - 1 - i]) { return false; } } return true; }


Aquí hay una forma de pitón. Nota: esto no es realmente tan "pitónico", pero demuestra el algoritmo.

def IsPalindromeString(n): myLen = len(n) i = 0 while i <= myLen/2: if n[i] != n[myLen-1-i]: return False i += 1 return True


Aquí hay una versión de Python que trata con diferentes casos, signos de puntuación y espacios en blanco.

import string def is_palindrome(palindrome): letters = palindrome.translate(string.maketrans("",""), string.whitespace + string.punctuation).lower() return letters == letters[::-1]

Editar: descaradamente se robó de la respuesta más clara de Blair Conrad para eliminar el procesamiento de la lista ligeramente torpe de mi versión anterior.


C #: LINQ

var str = "a b a"; var test = Enumerable.SequenceEqual(str.ToCharArray(), str.ToCharArray().Reverse());


C en la casa. (no estoy seguro si no quieres un ejemplo de C aquí)

bool IsPalindrome(char *s) { int i,d; int length = strlen(s); char cf, cb; for(i=0, d=length-1 ; i < length && d >= 0 ; i++ , d--) { while(cf= toupper(s[i]), (cf < ''A'' || cf >''Z'') && i < length-1)i++; while(cb= toupper(s[d]), (cb < ''A'' || cb >''Z'') && d > 0 )d--; if(cf != cb && cf >= ''A'' && cf <= ''Z'' && cb >= ''A'' && cb <=''Z'') return false; } return true; }

Eso volverá a ser cierto para "racecar", "Racecar", "race car", "racecar" y "RaCe cAr". Sería fácil modificarlo para incluir también símbolos o espacios, pero creo que es más útil contar solo las letras (e ignorar el caso). Esto funciona para todos los palíndromos que he encontrado en las respuestas aquí, y no he podido engañarlo con falsos negativos / positivos.

Además, si no te gusta bool en un programa "C", obviamente puede devolver int, con return 1 y return 0 para true y false respectivamente.


EDITAR: de los comentarios:

bool palindrome(std::string const& s) { return std::equal(s.begin(), s.end(), s.rbegin()); }

La forma c ++.

Mi implementación ingenua usando los iteradores elegantes. En realidad, probablemente verifique y se detenga una vez que su iterador hacia adelante haya pasado la mitad de su cadena.

#include <string> #include <iostream> using namespace std; bool palindrome(string foo) { string::iterator front; string::reverse_iterator back; bool is_palindrome = true; for(front = foo.begin(), back = foo.rbegin(); is_palindrome && front!= foo.end() && back != foo.rend(); ++front, ++back ) { if(*front != *back) is_palindrome = false; } return is_palindrome; } int main() { string a = "hi there", b = "laval"; cout << "String a: /"" << a << "/" is " << ((palindrome(a))? "" : "not ") << "a palindrome." <<endl; cout << "String b: /"" << b << "/" is " << ((palindrome(b))? "" : "not ") << "a palindrome." <<endl; }


El meta-código agnóstico del lenguaje entonces ...

rev = StringReverse(originalString) return ( rev == originalString );


En Ruby, convirtiendo a minúsculas y eliminando todo lo que no sea alfabético:

def isPalindrome( string ) ( test = string.downcase.gsub( /[^a-z]/, '''' ) ) == test.reverse end

Pero eso parece una trampa, ¿verdad? ¡Sin punteros ni nada! Así que aquí hay una versión C también, pero sin la bondad minúscula y despojamiento de caracteres:

#include <stdio.h> int isPalindrome( char * string ) { char * i = string; char * p = string; while ( *++i ); while ( i > p && *p++ == *--i ); return i <= p && *i++ == *--p; } int main( int argc, char **argv ) { if ( argc != 2 ) { fprintf( stderr, "Usage: %s <word>/n", argv[0] ); return -1; } fprintf( stdout, "%s/n", isPalindrome( argv[1] ) ? "yes" : "no" ); return 0; }

Bueno, eso fue divertido, ¿entiendo el trabajo? ^)


Este código de Java debería funcionar dentro de un método booleano :

Nota : solo debe verificar la primera mitad de los caracteres con la mitad posterior; de lo contrario, se superponen y duplican la cantidad de comprobaciones que deben realizarse.

private static boolean doPal(String test) { for(int i = 0; i < test.length() / 2; i++) { if(test.charAt(i) != test.charAt(test.length() - 1 - i)) { return false; } } return true; }


Estoy viendo muchas respuestas incorrectas aquí. Cualquier solución correcta debe ignorar el espacio en blanco y la puntuación (y cualquier carácter no alfabético en realidad) y debe ser insensible a mayúsculas y minúsculas.

Algunos buenos ejemplos de casos de prueba son:

"Un hombre, un plan, un canal, Panamá".

"Un Toyota es un Toyota".

"UN"

""

Además de algunos no palíndromos.

Solución de ejemplo en C # (nota: las cadenas vacías y nulas se consideran palíndromos en este diseño, si esto no se desea, es fácil de cambiar):

public static bool IsPalindrome(string palindromeCandidate) { if (string.IsNullOrEmpty(palindromeCandidate)) { return true; } Regex nonAlphaChars = new Regex("[^a-z0-9]"); string alphaOnlyCandidate = nonAlphaChars.Replace(palindromeCandidate.ToLower(), ""); if (string.IsNullOrEmpty(alphaOnlyCandidate)) { return true; } int leftIndex = 0; int rightIndex = alphaOnlyCandidate.Length - 1; while (rightIndex > leftIndex) { if (alphaOnlyCandidate[leftIndex] != alphaOnlyCandidate[rightIndex]) { return false; } leftIndex++; rightIndex--; } return true; }


Muchas formas de hacerlo. Supongo que la clave es hacerlo de la manera más eficiente posible (sin hacer un bucle en la cadena). Lo haría como una matriz de caracteres que se puede invertir fácilmente (usando C #).

string mystring = "abracadabra"; char[] str = mystring.ToCharArray(); Array.Reverse(str); string revstring = new string(str); if (mystring.equals(revstring)) { Console.WriteLine("String is a Palindrome"); }


Otro C ++ uno. Optimizado para velocidad y tamaño.

bool is_palindrome(const std::string& candidate) { for(std::string::const_iterator left = candidate.begin(), right = candidate.end(); left < --right ; ++left) if (*left != *right) return false; return true; }


Python no optimizado:

>>> def is_palindrome(s): ... return s == s[::-1]


Solución Java:

public class QuickTest { public static void main(String[] args) { check("AmanaplanacanalPanama".toLowerCase()); check("Hello World".toLowerCase()); } public static void check(String aString) { System.out.print(aString + ": "); char[] chars = aString.toCharArray(); for (int i = 0, j = (chars.length - 1); i < (chars.length / 2); i++, j--) { if (chars[i] != chars[j]) { System.out.println("Not a palindrome!"); return; } } System.out.println("Found a palindrome!"); }

}


Tenga en cuenta que en las soluciones de C ++ anteriores, hubo algunos problemas.

Una solución era ineficaz porque pasaba una cadena std :: por copia, y porque iteraba sobre todos los caracteres, en lugar de comparar solo la mitad de los caracteres. Entonces, incluso cuando descubrir que la cadena no era un palíndromo, continuó el ciclo, esperando su final antes de informar "falso".

El otro era mejor, con una función muy pequeña, cuyo problema era que no podía probar nada más que std :: string. En C ++, es fácil extender un algoritmo a un conjunto completo de objetos similares. Al convertir su std :: string en "T", habría funcionado en std :: string, std :: wstring, std :: vector y std :: deque. Pero sin modificaciones importantes debido al uso del operador <, std :: list estaba fuera de su alcance.

Mis propias soluciones intentan mostrar que una solución de C ++ no se detiene al trabajar en el tipo actual exacto, sino que se esforzará para trabajar cualquier cosa que se comporte de la misma manera, sin importar el tipo. Por ejemplo, podría aplicar mis pruebas de palindrome en std :: string, en el vector de int o en la lista de "Anything", siempre que Anything sea comparable a través de su operator = (compilación en tipos, así como en clases).

Tenga en cuenta que la plantilla puede incluso extenderse con un tipo opcional que se puede usar para comparar los datos. Por ejemplo, si desea comparar de una manera insensible a las mayúsculas y minúsculas o incluso comparar caracteres similares (como è, é, ë, ê y e).

Como el rey Leonidas hubiera dicho: "¡Plantillas, esto es C ++!"

Entonces, en C ++, hay al menos 3 formas principales de hacerlo, cada una lleva a la otra:

Solución A: en forma de c

El problema es que hasta C ++ 0X, no podemos considerar la matriz std :: string de caracteres como contiguos, por lo que debemos "hacer trampa" y recuperar la propiedad c_str (). Como lo estamos usando de manera solo lectura, debería estar bien ...

bool isPalindromeA(const std::string & p_strText) { if(p_strText.length() < 2) return true ; const char * pStart = p_strText.c_str() ; const char * pEnd = pStart + p_strText.length() - 1 ; for(; pStart < pEnd; ++pStart, --pEnd) { if(*pStart != *pEnd) { return false ; } } return true ; }

Solución B: una versión más "C ++"

Ahora, intentaremos aplicar la misma solución, pero a cualquier contenedor de C ++ con acceso aleatorio a sus elementos a través del operador []. Por ejemplo, cualquier std :: basic_string, std :: vector, std :: deque, etc. Operator [] es un acceso constante para esos contenedores, por lo que no perderemos velocidad indebida.

template <typename T> bool isPalindromeB(const T & p_aText) { if(p_aText.empty()) return true ; typename T::size_type iStart = 0 ; typename T::size_type iEnd = p_aText.size() - 1 ; for(; iStart < iEnd; ++iStart, --iEnd) { if(p_aText[iStart] != p_aText[iEnd]) { return false ; } } return true ; }

Solución C: ¡Plantilla powah!

Funciona con casi cualquier contenedor STL desordenado con iteradores bidireccionales. Por ejemplo, std :: basic_string, std :: vector, std :: deque, std :: list, etc. Por lo tanto, esta función se puede aplicar a todos los STL recipientes similares con las siguientes condiciones: 1 - T es un contenedor con iterador bidireccional 2 - El iterador de T apunta a un tipo comparable (a través del operador =)

template <typename T> bool isPalindromeC(const T & p_aText) { if(p_aText.empty()) return true ; typename T::const_iterator pStart = p_aText.begin() ; typename T::const_iterator pEnd = p_aText.end() ; --pEnd ; while(true) { if(*pStart != *pEnd) { return false ; } if((pStart == pEnd) || (++pStart == pEnd)) { return true ; } --pEnd ; } }


Tres versiones en Smalltalk, de la más tonta a la correcta.

En Smalltalk, = es el operador de comparación:

isPalindrome: aString "Dumbest." ^ aString reverse = aString

El mensaje #translateToLowercase devuelve la cadena como minúscula:

isPalindrome: aString "Case insensitive" |lowercase| lowercase := aString translateToLowercase. ^ lowercase reverse = lowercase

Y en Smalltalk, las cadenas son parte del marco de la Collection , puede usar el mensaje #select:thenCollect: así que aquí está la última versión:

isPalindrome: aString "Case insensitive and keeping only alphabetic chars (blanks & punctuation insensitive)." |lowercaseLetters| lowercaseLetters := aString select: [:char | char isAlphabetic] thenCollect: [:char | char asLowercase]. ^ lowercaseLetters reverse = lowercaseLetters


Una versión más al estilo Ruby de la versión de Hal''s Ruby :

class String def palindrome? (test = gsub(/[^A-Za-z]/, '''').downcase) == test.reverse end end

Ahora puedes llamar a palindrome? en cualquier cadena.


Una simple solución de Java:

public boolean isPalindrome(String testString) { StringBuffer sb = new StringBuffer(testString); String reverseString = sb.reverse().toString(); if(testString.equalsIgnoreCase(reverseString)) { return true; else { return false; } }


Una versión C ofuscada:

int IsPalindrome (char *s) { char*a,*b,c=0; for(a=b=s;a<=b;c=(c?c==1?c=(*a&~32)-65>25u?*++a,1:2:c==2?(*--b&~32)-65<26u?3:2:c==3?(*b-65&~32)-(*a-65&~32)?*(b=s=0,a),4:*++a,1:0:*++b?0:1)); return s!=0; }


Usando Java, usando Apache Commons String Utils:

public boolean isPalindrome(String phrase) { phrase = phrase.toLowerCase().replaceAll("[^a-z]", ""); return StringUtils.reverse(phrase).equals(phrase); }


Usar una buena estructura de datos generalmente ayuda a impresionar al profesor:

Presione la mitad de los caracteres en una pila (Longitud / 2).
Pop y compara cada char hasta la primera descalificación.
Si la pila tiene cero elementos: palíndromo.
* en el caso de una cuerda con una longitud impar, tira la mitad del char.


Windows XP (también podría funcionar en 2000) o posterior script BATCH:

@echo off call :is_palindrome %1 if %ERRORLEVEL% == 0 ( echo %1 is a palindrome ) else ( echo %1 is NOT a palindrome ) exit /B 0 :is_palindrome set word=%~1 set reverse= call :reverse_chars "%word%" set return=1 if "$%word%" == "$%reverse%" ( set return=0 ) exit /B %return% :reverse_chars set chars=%~1 set reverse=%chars:~0,1%%reverse% set chars=%chars:~1% if "$%chars%" == "$" ( exit /B 0 ) else ( call :reverse_chars "%chars%" ) exit /B 0


Ceceo:

(defun palindrome(x) (string= x (reverse x)))


Muestra de PHP :

$string = "A man, a plan, a canal, Panama"; function is_palindrome($string) { $a = strtolower(preg_replace("/[^A-Za-z0-9]/","",$string)); return $a==strrev($a); }

Elimina cualquier carácter no alfanumérico (espacios, comas, signos de exclamación, etc.) para permitir oraciones completas como las anteriores, así como palabras simples.


Delphi function IsPalindrome(const s: string): boolean; var i, j: integer; begin Result := false; j := Length(s); for i := 1 to Length(s) div 2 do begin if s[i] <> s[j] then Exit; Dec(j); end; Result := true; end;


boolean isPalindrome(String str1) { //first strip out punctuation and spaces String stripped = str1.replaceAll("[^a-zA-Z0-9]", ""); return stripped.equalsIgnoreCase((new StringBuilder(stripped)).reverse().toString()); }

Versión de Java