Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Bob1098 en 22 Agosto 2014, 22:43 pm



Título: Palindromo C++
Publicado por: Bob1098 en 22 Agosto 2014, 22:43 pm
Hola a todos. Quería comentarles una duda que tengo intentando resolver un ejercicio en C++. El enunciado se incluye en el código. El problema es que creo que esta todo bien y correcto, pero el resultado es que la función siempre devuelve true, o al menos eso parece. Aquí esta el código.

Código:
/*
5.Hacer un programa que contenga una función con el prototipo bool Palindromo(char palabra[40]);.
La función debe devolver true si la palabra es un palíndromo, y false si no lo es.
Una palabra es un palíndromo si cuando se lee desde el final al principio es igual que leyendo desde el principio,
por ejemplo: "Otto", o con varias palabras "Anita lava la tina", "Dábale arroz a la zorra el abad".
En estos casos debemos ignorar los acentos y los espacios, pero no es necesario que tu función haga eso,
bastará con probar cadenas como "anitalavalatina", o "dabalearrozalazorraelabad".
La función no debe hacer distinciones entre mayúsculas y minúsculas.
*/

#include <iostream>

using namespace std;

bool Palindromo(char palabra[40]);
int LongCad(char[]);

int main() {
char posiblePalindromo[40];
cout << "Introduce tu palindromo: ";
cin >> posiblePalindromo;

if (Palindromo(posiblePalindromo)) cout << "\nSi es un palindromo." << endl;
else cout << "\nNo es un palindromo." << endl;

cin.sync();
cin.get();
return 0;
}

bool Palindromo(char palabra[40]) {
char copia[40];
strcpy_s(copia, palabra);

int q = 0, p = LongCad(palabra), aux;
while (palabra[q] < p) {
aux = palabra[q];
palabra[q] = palabra[p];
palabra[p] = aux;
q++;
p--;
}

if (strcmp(palabra, copia) == 0) return true;
else return false;
}

int LongCad(char a[]) {
int i = 0;
while (a[i]) i++;
return 0;
}
[code=cpp][code=actionscript]
[/code][/code]

**EDITO: En el código no he puesto la librería necesaria "cstring" aun asi el código compilaba =S. Luego la puse y el mismo resultado.


Título: Re: Palindromo C++
Publicado por: kutcher en 22 Agosto 2014, 23:24 pm
La función debería quedar mas o menos así:

Código
  1. bool Palindromo(char palabra[40])
  2. {
  3.    char copia[40];
  4.    int q = 0, p;
  5.  
  6.    p = LongCad(palabra) - 1;
  7.  
  8.    while (palabra[q] != '\0')
  9.    {
  10.        copia[q] = palabra[p];
  11.        q++, p--;
  12.    }
  13.    copia[q] = '\0';
  14.  
  15.    if (strcmp(palabra, copia) == 0)
  16.        return true;
  17.    else
  18.        return false;
  19. }

Y en la función LongCad debes retornar i no cero
 


Título: Re: Palindromo C++
Publicado por: DarkMatrix en 22 Agosto 2014, 23:26 pm
Creo que tienes 2 errores en el codigo, el primero y mas notable es que la funcion LongCad siempre retorna cero y deberia retornar "i", el segundo es en esta linea "while (palabra[q] < p)", deberia ser "while (q < p)"

Código
  1. /*
  2. 5.Hacer un programa que contenga una función con el prototipo bool Palindromo(char palabra[40]);.
  3. La función debe devolver true si la palabra es un palíndromo, y false si no lo es.
  4. Una palabra es un palíndromo si cuando se lee desde el final al principio es igual que leyendo desde el principio,
  5. por ejemplo: "Otto", o con varias palabras "Anita lava la tina", "Dábale arroz a la zorra el abad".
  6. En estos casos debemos ignorar los acentos y los espacios, pero no es necesario que tu función haga eso,
  7. bastará con probar cadenas como "anitalavalatina", o "dabalearrozalazorraelabad".
  8. La función no debe hacer distinciones entre mayúsculas y minúsculas.
  9. */
  10.  
  11. #include <iostream>
  12. #include <string>
  13.  
  14. using namespace std;
  15.  
  16. bool Palindromo(char palabra[40]);
  17. int LongCad(char[]);
  18.  
  19. int main() {
  20. char posiblePalindromo[40];
  21.  
  22. cout << "Introduce tu palindromo: ";
  23. cin >> posiblePalindromo;
  24.  
  25. if (Palindromo(posiblePalindromo)) cout << "\nSi es un palindromo." << endl << endl;
  26. else cout << "\nNo es un palindromo." << endl << endl;
  27.  
  28. cin.sync();
  29. cin.get();
  30. return 0;
  31. }
  32.  
  33. bool Palindromo(char palabra[40]) {
  34. char copia[40];
  35. strcpy(copia, palabra);
  36. int q = 0, p = LongCad(palabra)-1, aux;
  37. while (q < p) {
  38. aux = palabra[q];
  39. palabra[q] = palabra[p];
  40. palabra[p] = aux;
  41. q++;
  42. p--;
  43. }
  44.  
  45. if (strcmp(palabra, copia) == 0) return true;
  46. else return false;
  47. }
  48.  
  49. int LongCad(char a[]) {
  50. int i = 0;
  51. while (a[i]) i++;
  52. return i;
  53. }


Título: Re: Palindromo C++
Publicado por: kutcher en 22 Agosto 2014, 23:40 pm
el segundo es en esta linea "while (palabra[q] < p)", deberia ser "while (q < p)"

El código es muy inconsistente al copiar directamente la palabra a la cadena copia no lograras comprobar si es o no palíndromo y con la condición del while dispuesta de es manera solo copiara la mitad de la palabra a la cadena destino

Saludos kutcher


Título: Re: Palindromo C++
Publicado por: DarkMatrix en 23 Agosto 2014, 00:07 am
palabra = "AnitaLavaLaTina"
copia = "AnitaLavaLaTina"

luego del bucle:

palabra = "aniTaLavaLatinA"

palindroma = (strcmp(palabra,copia) == 0)

Como el programa no tiene que distinguir entre mayusculas y minusculas, no importa como lo puse, fue para que se viera al invertir la palabra, la otra mitad no hace falta comprobarla ya que lo que hace el bucle es tomar la primera letra y cambiarla con la ultima, luego la segunda con la penultima, etc..., al llegar a la mitad ya se habran intercambiado todas las letras necesarias para saber si la palabra es palindroma, ya que si es asi la otra mitad sera igual a la ya intercambiada y la comparacion dara true, de lo contrario dara false.


Título: Re: Palindromo C++
Publicado por: Bob1098 en 23 Agosto 2014, 00:20 am
Vale, gracias a todos por las respuestas, la próxima vez me pondré a programar después de tomarme un buen café xd.

Aquí esta el código terminado, he corregido los fallos y añadido el "sistema" para las mayúsculas y minúsculas:

Código
  1. /*
  2. 5.Hacer un programa que contenga una función con el prototipo bool Palindromo(char palabra[40]);.
  3. La función debe devolver true si la palabra es un palíndromo, y false si no lo es.
  4. Una palabra es un palíndromo si cuando se lee desde el final al principio es igual que leyendo desde el principio,
  5. por ejemplo: "Otto", o con varias palabras "Anita lava la tina", "Dábale arroz a la zorra el abad".
  6. En estos casos debemos ignorar los acentos y los espacios, pero no es necesario que tu función haga eso,
  7. bastará con probar cadenas como "anitalavalatina", o "dabalearrozalazorraelabad".
  8. La función no debe hacer distinciones entre mayúsculas y minúsculas.
  9. */
  10.  
  11. #include <iostream>
  12. #include <cstring>
  13. #include <cctype>
  14.  
  15. using namespace std;
  16.  
  17. bool Palindromo(char palabra[40]);
  18. int LongCad(char[]); //Calcula la longitud de una cadena
  19.  
  20. int main() {
  21. char posiblePalindromo[40];
  22. cout << "Introduce tu palindromo: ";
  23. cin >> posiblePalindromo;
  24.  
  25. if (Palindromo(posiblePalindromo)) cout << "\nSi es un palindromo." << endl;
  26. else cout << "\nNo es un palindromo." << endl;
  27.  
  28. cin.sync();
  29. cin.get();
  30. return 0;
  31. }
  32.  
  33. bool Palindromo(char palabra[40]) {
  34. char copia[40];
  35.  
  36.  
  37. for (int i = 0; i <= LongCad(palabra) - 1; i++) if (isupper(palabra[i])) palabra[i] = tolower(palabra[i]); //Convierte todos los caracteres a minuscula
  38.  
  39. strcpy_s(copia, palabra); //Se copia la cadena para una posterior comparación
  40.  
  41. int q = 0, p = LongCad(palabra) - 1, aux;
  42. while (q < p) { //Invierte los elementos de la cadena "palabra"
  43. aux = palabra[q];
  44. palabra[q] = palabra[p];
  45. palabra[p] = aux;
  46. q++;
  47. p--;
  48. }
  49.  
  50. if (strcmp(palabra, copia) == 0) return true;
  51. else return false;
  52. }
  53.  
  54. int LongCad(char a[]) {
  55. int i = 0;
  56. while (a[i]) i++;
  57. return i;
  58. }
  59.  
  60.  


Título: Re: Palindromo C++
Publicado por: kutcher en 23 Agosto 2014, 00:28 am
Como el programa no tiene que distinguir entre mayusculas y minusculas, no importa como lo puse, fue para que se viera al invertir la palabra, la otra mitad no hace falta comprobarla ya que lo que hace el bucle es tomar la primera letra y cambiarla con la ultima, luego la segunda con la penultima, etc..., al llegar a la mitad ya se habran intercambiado todas las letras necesarias para saber si la palabra es palindroma, ya que si es asi la otra mitad sera igual a la ya intercambiada y la comparacion dara true, de lo contrario dara false.

Es verdad no me tome el tiempo de leerlo con detalle jaja

Saludos kutcher


Título: Re: Palindromo C++
Publicado por: leosansan en 23 Agosto 2014, 20:10 pm
Lo que no me acaba de convencer es la necesidad de usar una copia de "palabra". Podrías comparar directamente los caracteres equidistantes de palabra, algo como:

Código
  1. bool Palindromo(char palabra[40]) {
  2.  nt q = 0, p = (LongCad(palabra) - 1);
  3.  while (q < p) {
  4.    if ( tolower (palabra[q]) != tolower (palabra[p]) )
  5.      return false;
  6.    q++, p--;
  7.  }
  8.  return true;
  9. }

"Creo" que así funcionará.

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

EDITADO con la observación de Blaster.


Título: Re: Palindromo C++
Publicado por: Blaster en 23 Agosto 2014, 20:49 pm
Seria mas apropiado realizar el decremento e incremento fuera del while justo después de la primera comparación:

Código
  1. while (q < p)
  2. {
  3.   if (palabra[q] != palabra[p])
  4.       return false;
  5.   q++, p--;
  6. }

Tu código al procesar una cadena como esta arenere retornara true

Saludos


Título: Re: Palindromo C++
Publicado por: leosansan en 23 Agosto 2014, 21:03 pm
Seria mas apropiado realizar el decremento e incremento fuera del while justo después de la primera comparación:
...........................
Saludos

Por algo puse "Creo", no sé por qué pero algo me decía que no estaba bien.  ;)

Gracias por la observación. Ya edité el mensaje anterior donde recojo lo que mencionas.

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Palindromo C++
Publicado por: Blaster en 23 Agosto 2014, 21:36 pm
no sé por qué pero algo me decía que no estaba bien. 

Pero de igual manera podrías inicializar q a -1 y no restarle 1 a p:

Código
  1. int q = -1, p = LongCad(palabra);
  2. while (q++ < p--)
  3.    if (palabra[q] != palabra[p])
  4.       return false;
  5. return true;

Saludos


Título: Re: Palindromo C++
Publicado por: leosansan en 23 Agosto 2014, 22:45 pm
Pero de igual manera podrías inicializar q a -1 y no restarle 1 a p:
.......................................

Y ya puestos podríamos ahorrarnos una variable:

Código
  1. bool Palindromo(char palabra[40]) {
  2.  int p = LongCad ( palabra ) ;
  3.  while ( ( p-- ) > ( LongCad ( palabra ) - 1 ) / 2 )
  4.    if ( tolower (palabra [ p ] ) != tolower ( palabra [ LongCad ( palabra ) - 1 - p ] ) )
  5.      return false;
  6.  return true;
  7. }

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)