Autor Tema: recursivo comprobar palabra palíndromo búsqueda lineal en arreglo C (lenguajec)  (Leído 27203 veces)

rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Buenas tardes.

He  escrito el siguiente código para ver si una palabra es un palíndromo a través de una función recursiva.

El problema está en que curiosamente siempre devuelve 0 ¡¡¡Aunque por probar puse que fuera o no palíndromo devolviera 1!!!  La verdad esque por más que he buscado, no encuentro el fallo de porque devuelve siempre el valor 0:

Pongo el código a continuación.

Muchas gracias por todo

Código: [Seleccionar]
// Ejercicio 6.33: Palíndromos //

#include <stdio.h>

int pruebaPalindromo(char palabra[], int longitud );

main()
{
      int palindromo;
      char palabra[20];
      int longitud = 0;
     
      printf("Por favor, introduzca una palabra: ");
      scanf("%s", palabra);
     
      while(palabra[longitud] != '\0' )
      {
            longitud++;
      }
     
      palindromo = pruebaPalindromo(palabra, longitud - 1 );
      printf("\npalindromo  %d\n\n",palindromo);
     
      if(palindromo == 1)
         printf("\nLa palabra introducida ES un pal%cndromo\n\n", 161);
         
      if(palindromo == 0)
         printf("\nLa palabra introducida NO ES un pal%cndromo\n\n", 161);
     
     
      system("pause");
      return 0;
}

int pruebaPalindromo (char palabra[], int longitud )
{
    static int letra = 0;
   
    printf("%d\n", letra);
   
             if (palabra[letra] != palabra[longitud-letra] || letra > longitud/2 )
             {
                 printf("Longitud es %d\n", longitud);
                 printf("La letra es %d\n", letra);
                 if(letra <= longitud / 2   )
                    return 1;
                 else
                    return 1; // Debería de ser 0, pero puse 1 para ver si aún así seguía devolviendo 0//
             }
             
             else
             {
                     
                 printf("'%c' es igual a '%c'\n", palabra[letra],palabra[longitud  - letra] );     
                 letra++;
                 pruebaPalindromo(palabra, longitud );
                 
             }
   
}
« Última modificación: 11 de Mayo 2015, 18:59 por Alex Rodríguez »

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #1 en: 09 de Junio 2014, 20:23 »
Para plantear una función recursiva tienes que definir cuál es el caso base que te permite terminar la recursión, así como una condición que haga ir evolucionando la recursión.

Pareces tratar de hacer evolucionar la recursión usando la variable letra, pero letra está declarada dentro de la función recursiva, con lo cual se crean tantas copias de esta variable como llamadas se hagan a la función.

La llamada pruebaPalindromo(palabra, longitud ); siempre te estaría devolviendo lo mismo, no habría evolución... no veo claro cómo lo quieres plantear ¿cuál es tu idea?

rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #2 en: 09 de Junio 2014, 20:32 »
A ver, mi idea (que creo que es lo que he hecho aunque no estoy muy seguro ya) es que la función recursiva acabe cuando deje de haber coincidencia entre las letras, o se llegue a la mitad de la palabra, a través de la variable letra(por eso la puse static, para que guarde los resultados).
Y todo transcurre de forma correcta hasta que acaba la función recursiva, que en ese caso devuelve siempre 0 (aunque no he marcado que devuelva 0 en ningún sitio para ver si veía el error).

rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #3 en: 09 de Junio 2014, 20:39 »
mira, he hecho otro ejercicio de recursividad(esta vez de búsqueda lineal a través de una matriz)  y me pasa lo mismo, se ejecuta todo bien,pero luego al devolver un resultado, devuelve lo que no debe.
Pongo el código a continuación, porque creo que el fallo es el mismo que en el ejercicio de los palíndromos.

Código: [Seleccionar]
// Ejercicio 6.34: búsqueda lineal (recursivo) //

#include <stdio.h>
#define TAMANIO 100

/* prototipo de la función */
int busquedaLineal( const int arreglo[], int llave, int tamanio );

/* la función main comienza la ejecución del programa */
int main()
{   
   int a[ TAMANIO ]; /* crea el arreglo a */
   int x; /* contador para inicializar los elementos de 0 a 99 del arreglo a */
   int llaveBusqueda; /* valor para localizar en el arreglo a */
   int elemento; /* variable para almacenar la ubicación de llaveBusqueda o -1 */

   /* crea los datos */
   for ( x = 0; x < TAMANIO; x++ ) {
      a[ x ] = 2 * x;
   } /* fin de for */

   printf( "Introduzca la llave de busqueda entera:\n" );
   scanf( "%d", &llaveBusqueda );

   /* intenta localizar llaveBusqueda en el arreglo a */
   elemento = busquedaLineal( a, llaveBusqueda, TAMANIO );

   /* despliega los resultados */
   if ( elemento != -1 ) {
      printf( "Encontre el valor en el elemento %d\n", elemento );
   } /* fin de if */
   else {
      printf( "Valor no encontrado\n" );
   } /* fin de else */

   system("pause");
   return 0; /* indica terminación exitosa */

} /* fin de main */

/* compara la llave con cada elemento del arreglo hasta que localiza el elemento
   o hasta que alcanza el final del arreglo; devuelve el subíndice del elemento
   si lo encontró o -1 si no lo encontró */
int busquedaLineal( const int arreglo[], int llave, int tamanio )
{
   static int n = 0; /* contador */

   /* ciclo a través del arreglo */
   if (n < tamanio) {

      if ( arreglo[ n ] == llave ) {
         return n; /* devuelve la ubicación de la llave */
      } /* fin de if */
      else
      {
          printf("%d\n", n);
          n++;
          busquedaLineal( arreglo, llave, tamanio );
      }

   } /* fin de if */
   
   else
   {
   return -1; /* llave no encotrada */
   }

} /* fin de la función busquedaLineal */


Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #4 en: 10 de Junio 2014, 10:40 »
A mí el código que has puesto sí me funciona bien, me devuelve el índice del array donde se encuentra el elemento buscado, pero el diseño de la recursión con una variable estática dentro de la función recursiva no es un buen diseño por varios motivos. Para no hacer esto hay varias soluciones posibles, una de ellas introducir el parámetro de evolución dentro de la propia llamada recursiva (con lo cual no dependes de una variable estática), como en este código:

Código: [Seleccionar]
// Ejercicio 6.34: búsqueda lineal (recursivo) //

#include <stdio.h>
#define TAMANIO 100

/* prototipo de la función */
int busquedaLineal( const int arreglo[], int llave, int tamanio, int n );

/* la función main comienza la ejecución del programa */
int main() {
    int a[ TAMANIO ]; /* crea el arreglo a */
    int x; /* contador para inicializar los elementos de 0 a 99 del arreglo a */
    int llaveBusqueda; /* valor para localizar en el arreglo a */
    int elemento; /* variable para almacenar la ubicación de llaveBusqueda o -1 */

    /* crea los datos */
    for ( x = 0; x < TAMANIO; x++ ) {
        a[ x ] = 2 * x;
    } /* fin de for */

    printf( "Introduzca la llave de busqueda entera:\n" );
    scanf( "%d", &llaveBusqueda );

    /* intenta localizar llaveBusqueda en el arreglo a */
    elemento = busquedaLineal( a, llaveBusqueda, TAMANIO, 0);

    /* despliega los resultados */
    if ( elemento != -1 ) {
        printf( "Encontre el valor en el elemento %d\n", elemento );
    } /* fin de if */
    else {
        printf( "Valor no encontrado\n" );
    } /* fin de else */

    system("pause");
    return 0; /* indica terminación exitosa */

} /* fin de main */

/* compara la llave con cada elemento del arreglo hasta que localiza el elemento
   o hasta que alcanza el final del arreglo; devuelve el subíndice del elemento
   si lo encontró o -1 si no lo encontró */
int busquedaLineal( const int arreglo[], int llave, int tamanio, int n ) {

    /* ciclo a través del arreglo */
    if (n < tamanio) {

        if ( arreglo[ n ] == llave ) {
            return n; /* devuelve la ubicación de la llave */
        } /* fin de if */
        else {
            printf("%d\n", n);
            busquedaLineal( arreglo, llave, tamanio, n+1 );
        }

    } /* fin de if */

    else {
        return -1; /* llave no encotrada */
    }

} /* fin de la función busquedaLineal */

Aquí puedes ver algunas referencias:

Rather than using a static variable for index, it would be better to pass it in as an argument to recursive; otherwise, the function is non-reentrant.

http://stackoverflow.com/questions/1697777/recursion-using-c-language

Which has the benefit of not requiring the caller to supply an argument to foo() and also you don't need a static variable (which I always feel is a bad idea).

http://stackoverflow.com/questions/1316809/recursive-function-with-static-variable

rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #5 en: 12 de Junio 2014, 12:39 »
buenos dias.
He modificado el código pero sigue sin funcionar, me da valores raros.
El código es este:
Código: [Seleccionar]
// Ejercicio 6.34: búsqueda lineal (recursivo) //

#include <stdio.h>
#define TAMANIO 100

/* prototipo de la función */
int busquedaLineal( const int arreglo[], int llave, int tamanio, int n );

/* la función main comienza la ejecución del programa */
int main()
{   
   int a[ TAMANIO ]; /* crea el arreglo a */
   int x; /* contador para inicializar los elementos de 0 a 99 del arreglo a */
   int llaveBusqueda; /* valor para localizar en el arreglo a */
   int elemento; /* variable para almacenar la ubicación de llaveBusqueda o -1 */

   /* crea los datos */
   for ( x = 0; x < TAMANIO; x++ ) {
      a[ x ] = 2 * x;
   } /* fin de for */

   printf( "Introduzca la llave de busqueda entera:\n" );
   scanf( "%d", &llaveBusqueda );

   /* intenta localizar llaveBusqueda en el arreglo a */
   elemento = busquedaLineal( a, llaveBusqueda, TAMANIO, 0 );
printf( "elemento = %d\n", elemento );
   /* despliega los resultados */
   if ( elemento != -1 ) {
      printf( "Encontre el valor en el elemento %d\n", elemento );
   } /* fin de if */
   else {
      printf( "Valor no encontrado\n" );
   } /* fin de else */

   system("pause");
   return 0; /* indica terminación exitosa */

} /* fin de main */

/* compara la llave con cada elemento del arreglo hasta que localiza el elemento
   o hasta que alcanza el final del arreglo; devuelve el subíndice del elemento
   si lo encontró o -1 si no lo encontró */
int busquedaLineal( const int arreglo[], int llave, int tamanio, int n )
{
    printf("llave=%d  tamanio = %d  n = %d\n",llave,tamanio, n);
   

      if ( arreglo[ n ] == llave || n == -1 ) {
           printf( "n = %d\n", n );
         return n; /* devuelve la ubicación de la llave */
      } /* fin de if */
      else
      {
          busquedaLineal( arreglo, llave, tamanio, n+1 );
      }

 
} /* fin de la función busquedaLineal */

Puse printf a la salida de la función para ver el valor de n, y tambien en main para ver el valor de la variable elemento.
En teoría elemento debería ser igual a 'n', sin embargo, da igual la cifra que se ponga, siempre tiene valor 2686324.
Sinceramente no entiendo que falla y me estoy volviendo un poco loco.
Agradecería cualquier ayuda

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #6 en: 12 de Junio 2014, 14:17 »
A mí el código que te puse en la respuesta anterior sí me funciona bien, o eso parece. Por ejemplo:

Introduzca la llave de búsqueda entera: 6
0
1
2
Encontre el valor en el elemento 3



Introduzca la llave de búsqueda entera: 5
0
1
2
...
hasta 99
Valor no encontrado


Introduzca la llave de búsqueda entera: 100
0
1
2
...
Encontre el valor en el elemento 50


Si tú no obtienes estos resultados puede estar relacionado con algún detalle de la configuración del ide o compilador que estés utilizando.

rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #7 en: 12 de Junio 2014, 16:06 »
Muchas gracias.

He probado tu código y me da el mismo resultado que en lo que yo modifiqué (2686324).
Asique supongo que será problema del compilador.

Uso dev-c++. Sabes alguna forma para que lo pudiera arreglar.

Muchas gracias

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #8 en: 12 de Junio 2014, 18:08 »
Habría que revisar con calma muchas cosas para poder determinar algo, el problema puede venir por distintos motivos.

Aparentemente dev-c++ es un proyecto abandonado, y la alternativa sería Orwell Dev-C++, http://sourceforge.net/projects/orwelldevcpp/

Pero desconozco si va bien o no.

Generalmente codeblocks suele ir bien, http://www.codeblocks.org/downloads/26

codeblocks-13.12mingw-setup.exe te instala el ide y el compilador mingw.

Si te decides por instalar otro entorno, posiblemente si sería aconsejable desinstalar previamente lo que tengas, de cualquier manera ten cuidado con las instalaciones y desinstalaciones porque podrías perder cosas si no haces copia de seguridad. También se presenta el problema de no tener garantías sobre el correcto funcionamiento de la nueva instalación, así que no tomaría la decisión demasiado rápido.


rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #9 en: 12 de Junio 2014, 19:55 »
Buenas tardes.

Entonces, que entorno de desarrollo me recomendarias para windows? y para linux-ubuntu? Es mejor usar un entorno de desarrollo o compilarlo a traves de la consola?

Muchas gracias

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #10 en: 12 de Junio 2014, 20:03 »
Codeblocks, lo tienes disponible tanto para windows como para linux y te permite trabajar tanto con c como con c++

La mayoría de la gente prefiere trabajar con un entorno de desarrollo porque ofrece más comodidades (yo mismo suelo trabajar así normalmente).


rackdon

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 50
    • Ver Perfil
Re:comprobar si una palabra es un palíndromo
« Respuesta #11 en: 12 de Junio 2014, 21:51 »
He estado mirando en entornos de desarrollo para ubuntu, y los que más me han convencido son codeblocks, eclipse y anjuta. Da lo mismo usar uno que otro? ventajas o desventajas de alguno de ellos?. Esque estoy empezando con la programación por mi cuenta y además me instale linux hace nada asique estoy perdido por partida doble ejejeje.
Muchas gracias por toda tu ayuda.
Un saludo
« Última modificación: 12 de Junio 2014, 23:44 por rackdon »

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".