elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Programa para detectar palindromos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Programa para detectar palindromos  (Leído 7,541 veces)
Error 404:

Desconectado Desconectado

Mensajes: 58



Ver Perfil
Programa para detectar palindromos
« en: 3 Septiembre 2014, 13:23 pm »

Hola a todos, antes de nada, ya se que saqué este hilo hace algún tiempo, pero sigo teniendo un problema al que no consigo darle la solución. El objetivo del programa que estoy intentando crear es que al introducir una cadena de caracteres, éste te diga si esa cadena es o no un palíndromo (que se lee igual de izquierda a derecha y de derecha a izquierda (ejemplo otto)).
He conseguido compilar el código sin que me salga ningún error ni ningún warning, sin embargo cuando lo ejecuto, al introducir la cadena, no hace nada  :huh:
Les dejo el código por si me pudieran ayudar. Gracias de antemano a todos.
Código
  1.  
  2. #include <iostream>
  3. #include <cstring>
  4.  
  5. using namespace std;
  6.  
  7. bool palindromo(char cadena[100]);
  8.  
  9. int main(){
  10.  
  11.    char cadena[100];
  12.  
  13.    cout << "Introduzca una palabra o cadena de ellas sin utilizar espacios y/o" << endl;
  14.  
  15.    cout << " mayusculas, minusculas, acentos, etc. El programa le dira si la" << endl;
  16.  
  17.    cout << " cadena introducida es un palindromo."<< endl;
  18.  
  19.  
  20.  
  21.    cin >> cadena;
  22.  
  23.    cin.get();
  24.  
  25.    if (palindromo(cadena)) cout<< "Es un palindromo.";
  26.  
  27.    else cout<< " No es un palindromo.";
  28.  
  29.  
  30. cin.get();
  31.  
  32. return 0;
  33.  
  34. }
  35.  
  36. bool palindromo(char cadena[100])
  37. {
  38.  
  39.     int n;
  40.  
  41.     int j = sizeof(cadena)/sizeof(cadena[0]);
  42.  
  43.     int k = 0;
  44.  
  45.     do{
  46.  
  47.         if (cadena[k]!=cadena[j])(n=0);
  48.  
  49.         else {                                      
  50.  
  51.              k++;
  52.  
  53.              j--;
  54.  
  55.              n=1;
  56.  
  57.              }
  58.  
  59.         } while(k != j-1 || n!=0);
  60.  
  61.         if (n==1) return true; else return false;
  62.  
  63. }
  64.  
  65.  


En línea

Si se puede imaginar, se puede programar.
ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: Programa para detectar palindromos
« Respuesta #1 en: 3 Septiembre 2014, 14:51 pm »

Hazlo haciendo que la variable 'j' sea strlen(cadena)-1.

Bueno, eso, y otros cambios que has de hacerle.


En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Programa para detectar palindromos
« Respuesta #2 en: 3 Septiembre 2014, 15:02 pm »

Para las cadenas, usa la clase string en vez de char*:

Código
  1. #include <string>
  2.  
  3. // const& implica una referencia constante
  4. bool palindromo( const std::string& cadena );
  5.  
  6. // ...
  7.  
  8. std::string cadena;
  9.  
  10. // ...
  11.  
  12. std::cin >> cadena;
  13.  
  14. // ...

Además, te complicas demasiado la forma de recorrer la cadena:

Código
  1. int j = sizeof(cadena)/sizeof(cadena[0]);

sizeof(cadena) te va a dar 100... realmente tiene 100 caracteres tu cadena???, no verdad??

Código
  1. int j = strlen(cadena) - 1;

O si estás haciendo uso de la clase string:

Código
  1. int j = cadena.length( ) - 1;

Por otro lado, haces un uso un tanto complicado de la variable 'n':

* No la inicializas al principio... eso es peligroso
* Solo va a tener dos posibles estados... mejor declararla como bool
* Poner nombres significativos a las variables facilita la lectura y mantenimiento del código.

Código
  1. bool esPalindromo = true;
  2.  
  3. do
  4. {
  5.  if ( cadena[ k ] != cadena[ j ] )
  6.    esPalindromo = false;
  7.  else
  8.  {
  9.    k++;
  10.    j--;
  11.  }
  12. } while ( k < j && esPalindromo ); // k != j - 1 ¿¿??

Aún con todo, insisto, hay formas más sencillas de hacer esto. Por ejemplo copiar la cadena invertida en otro buffer (o en otra instancia de tipo string) y comparar ambas cadenas (con strcmp o con el operador == según el caso )... si son iguales entonces hay palíndromo:

Código
  1. int main( )
  2. {
  3.  std::string cadena;
  4.  
  5.  std::cout << "Introduce una cadena: " << std::endl;
  6.  
  7.  std::cin >> cadena;
  8.  
  9.  std::string cadenaInvertida{ cadena.rbegin( ), cadena.rend( ) };
  10.  
  11.  if ( cadena == cadenaInvertida )
  12.    std::cout << "Es palíndromo" << std::endl;
  13.  else
  14.    std::cout << "NO es palíndromo" << std::endl;
  15. }



PD.: Este es mi mensaje nº 1.000 yuhuuuu XDDD
« Última modificación: 3 Septiembre 2014, 15:07 pm por eferion » En línea

vk496

Desconectado Desconectado

Mensajes: 205


Ver Perfil
Re: Programa para detectar palindromos
« Respuesta #3 en: 3 Septiembre 2014, 17:56 pm »

Me ha intrigado tu propuesta, y me puse a hacerlo... pero en Bash (no domino el C/C++)

Código
  1. #!/bin/bash
  2.  
  3. verde="\033[1;32m"
  4. rojo="\033[1;31m"
  5. rescolor="\e[0m"
  6.  
  7. frase=$(echo $@ | sed 's/ //g' | iconv -t ASCII//TRANSLIT | tr [:upper:] [:lower:])
  8. ifrase=$(echo $frase | rev)
  9.  
  10. if [ -z "$frase" ]; then
  11. echo Introduzca una palabra/frase como parámetro:
  12. echo
  13. echo -e $0 ${rojo}dábale arroz a la zorra el Abad$rescolor
  14. exit 1
  15. fi
  16.  
  17.  
  18. if [ "$frase" = "$ifrase" ]; then
  19. echo -e $verde$@$rescolor es un POLINDROMO
  20. echo
  21. echo ":)"
  22. else
  23. echo -e "$rojo$@$rescolor no es un polindromo :("
  24. fi

Espero que te sirva

Salu2
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Programa para detectar palindromos
« Respuesta #4 en: 3 Septiembre 2014, 18:06 pm »

Además, te complicas demasiado la forma de recorrer la cadena:

Código
  1. int j = sizeof(cadena)/sizeof(cadena[0]);

sizeof(cadena) te va a dar 100
Ya que todo parámetro declarado como "T [N]" se procesa en realidad como "T *" el resultado de "sizeof(cadena)" sera igual a "sizeof(char *)". Por supuesto no deja de ser un error y hay que cambiar la aproximación a, como sugieres, el uso de la función strlen.

En el caso de cadenas "a la C" una aproximación en la misma linea mas propia de C que de C++ es:
Código
  1. bool palindromo(char const *str)
  2. {
  3.   size_t i;
  4.   size_t j = strlen(str) - 1;
  5.  
  6.   for (i = 0; i < j && str[i] == str[j]; i++, j--)
  7.      ;
  8.  
  9.   return i >= j;
  10. }

Un detalle a tener en cuenta es que no hay protección en caso de una cadena vacía (solo el cero), en ese caso daría resultados incorrectos.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Error 404:

Desconectado Desconectado

Mensajes: 58



Ver Perfil
Re: Programa para detectar palindromos
« Respuesta #5 en: 3 Septiembre 2014, 18:08 pm »

vk496 me temo que no se absolutamente nada de Bash :-\ pero gracias por la respuesta y me alegro que te resulte interesante mi propuesta  :rolleyes:

Eferion, he seguido algunos de tus consejos, y ahora me avisa de cuando es un palíndromo, pero si pongo una cadena/palabra que no lo es no me dice nada. He conseguido avanzar a que me diga cuando sí lo es, pero no consigo hacer que me diga cuando no.
Antes de ponerte el código actual, decirte que estoy siguiendo un manual pues aún no se mucho (como habrás notado), por eso no he usado el último consejo que me has dicho, pues aún no he llegado a eso, y la clase string, me temo que tampoco la he dado aún.
Bueno, dejo el código actual, para ver si alguien ve mi fallo, agradezco mucho las respuestas de verdad, aunque me gustaría que no solo me digáis lo que debo poner o quitar, sino que me intentéis explicar más o menos. el por qué falla como lo tengo, para así saber porque no funciona y evitar que ese fallo me suceda en más ocasiones.

rir3760 la verdad es que no se qué es size_t,´soy bastante nuevo y solo sé lo que he estudiado en el manual que leo, y no he visto nada de eso, por lo que no he entendido nada  :huh: :huh: :huh:

Dicho esto..


Código
  1.  
  2. #include <iostream>
  3. #include <cstring>
  4.  
  5. using namespace std;
  6.  
  7. bool palindromo(char cadena[100]);
  8.  
  9. int main(){
  10.  
  11.    char cadena[100];
  12.  
  13.    cout << "Introduzca una palabra o cadena de ellas sin utilizar espacios y/o" << endl;
  14.  
  15.    cout << " mayusculas, minusculas, acentos, etc. El programa le dira si la" << endl;
  16.  
  17.    cout << " cadena introducida es un palindromo."<< endl;
  18.  
  19.  
  20.  
  21.    cin >> cadena;
  22.  
  23.    cin.get();
  24.  
  25.    if (palindromo(cadena)) cout<< "Es un palindromo.";
  26.  
  27.    else cout<< " No es un palindromo.";
  28.  
  29.  
  30. cin.get();
  31.  
  32. return 0;
  33.  
  34. }
  35.  
  36. bool palindromo(char cadena[100])
  37. {
  38.  
  39.  
  40.     bool esPalindromo = true;
  41.     int j = strlen(cadena)-1;
  42.     int k = 0;
  43.  
  44.     do{
  45.  
  46.         if (cadena[k]!=cadena[j]){
  47.         esPalindromo = false;
  48. }
  49. else {                                      
  50.  
  51.              k++;
  52.  
  53.              j--;
  54.  
  55.              }
  56.  
  57.         } while(k < j && palindromo);
  58.     if (esPalindromo) return true;
  59.     else return false;
  60.  
  61.  
  62. }
  63.  
  64.  



Vale, ya me he dado cuenta del error, el fallo estaba en la línea 57
Código
  1. } while(k < j && palindromo);
  2.  

No es eso lo que debo poner, sino

Código
  1. } while(k < j && esPalindromo);
  2.  

Al hacer ese pequeño cambio ya funciona todo correctamente, aunque si alguien me pudiera explicar por qué no hacía nada, porque entiendo que diera fallo, pero no que no saliera nada  :huh:
« Última modificación: 6 Septiembre 2014, 10:50 am por Eternal Idol » En línea

Si se puede imaginar, se puede programar.
rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Programa para detectar palindromos
« Respuesta #6 en: 5 Septiembre 2014, 21:34 pm »

Porque "palindromo" es un puntero y cuando estos se convierten a booleanos los distintos de NULL resultan en true y los iguales en false, tu bucle se procesa de esta forma:
Código
  1. do {
  2.   if (cadena[k] != cadena[j]){
  3.      esPalindromo = false;
  4.   }else {
  5.      k++;
  6.      j--;
  7.   }
  8. }while (k < j && true); // palindromo != NULL ==> true

Los resultados del operador && en los dos casos que nos importan son:
Código:
false && true ==> false
 true && true ==> true

Como puedes ver (en este caso en particular) el segundo operando no importa, el resultado solo lo decide el primero, tenemos:
Código
  1. do {
  2.   if (cadena[k] != cadena[j]){
  3.      esPalindromo = false;
  4.   }else {
  5.      k++;
  6.      j--;
  7.   }
  8. }while (k < j);

Por eso, si los caracteres a comparar en cualquier momento son distintos, se entra en un bucle infinito: para terminar se debe modificar el valor de los contadores "i" y "j" pero la rama de ejecución donde ello se realiza nunca se ejecuta.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
Error 404:

Desconectado Desconectado

Mensajes: 58



Ver Perfil
Re: Programa para detectar palindromos
« Respuesta #7 en: 6 Septiembre 2014, 09:37 am »

ah, creo que lo he entendido, gracias rir3760, y a todos por la ayuda ;-)
En línea

Si se puede imaginar, se puede programar.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines