Tag Archives: cadenas

Saber si es palíndromo o no, de forma recursiva 2da parte

Pues la idea que se me ocurrió en el otro post resultó ser más sencilla de lo que me imaginé, y ahora sí la función recursiva se ve mucho mejor, ya es mucho más que un ciclo disfrazado.

Comenté extensivamente el código, así que aquí está:

#include
#include
using namespace std;
int len, n=0;

string chk4palindrosity(string thestr)
{
    if(thestr[0] == thestr[thestr.length() - 1]) // comparar primer caracter con ultimo
    {
        n++;
        if(n == len / 2) // si el numero de veces que la comparación ha sido cierta es...
            return "Si es palindromo!"; // igual a la mitad de los caracters, es palindromo
        thestr.erase(0, 1); // borramos primer caracter
        thestr.erase(thestr.length() - 1, 1); // borramos ultimo
        return chk4palindrosity(thestr); // llamamos a la función con el string recortado
    }
    else // si una de las comparaciones no es cierta, no es palíndromo
        return "No es palindromo";
}

int main()
{
    char inputf[50]={0}, input[50], *parte;
    cout<<"Introduce un palindromo: "; cin.getline(input, 'n');

    parte = strtok(input, " ");                 //
    strcat(inputf, parte);                     //
    while((parte = strtok(NULL, " ")) != NULL) //
        strcat(inputf, parte);               // quitar espacios del array

    string thestr(inputf); // convertir array en string para facilitar operaciones
    len = thestr.length(); // obtener longuitud del string
    if(len == 1)
        cout << "Si es palindromo!";
    else
        cout << chk4palindrosity(thestr); // llamar a la funcion e imprimir lo que retorne
    cin.get();
}

Lo que hace la función recursiva es comparar el primer caracter con el último, si son iguales recortarlos y llamarse; si no, no es palíndromo. Cualquier duda ya saben que los comentarios están abiertos.

Advertisements

Saber si es palíndromo o no, de forma recursiva

Hace unos días me pidieron por correo un programa que nos dijera si un string es palíndromo o no, pero usando una función recursiva. Me pareció interesante aunque raro que pidieran hacerlo de forma recursiva.

Tal vez recuerden que ya había publicado aquí una forma de saber si un string es palíndromo o no, el cual he descubierto (ahora que hice este otro) que no es muy eficiente.

Bueno pues el código es este:

#include
#include
using namespace std;
char cadenaf[50]={0}; int len, n=0;

string chk4palindrosity(int c)
{
    if(cadenaf[c] == cadenaf[len-1-c])
    {
        n++;
        if(n == len/2)
            return "Si es palindromo!";
        return chk4palindrosity(c+1);
    }
    else
        return "No es palindromo";
}

int main()
{
    char cadena[50],*parte;
    cout<<"Introduce un palindromo: "; cin.getline(cadena,50,'n');

    parte = strtok(cadena," ");                 //
    strcat(cadenaf,parte);                     //
    while((parte = strtok(NULL," ")) != NULL) //
        strcat(cadenaf,parte);               // quitar espacios del string

    len = strlen(cadenaf);
    cout << chk4palindrosity(0);
    cin.get();
}

La verdad es que es la función es recursiva de puro milagro. Lo que hice fue transformar el ciclo que checaba que los caracteres fueran iguales en una función en la que se aumenta una variable cada vez que se llama a sí misma.

El código ahora es más eficiente por dos simples razones:

  1. Se detiene y da el resultado a la primera comparación de caracteres que no sean iguales. Si el primer y el último caracter no son iguales, no es palíndromo y ya no sigue analizando los demás.
  2. Sólo checa la mitad de los caracteres. Si la mitad de los caracteres corresponden a la configuración de un palíndromo, ya no hay porqué seguir analizando la otra mitad.

Tal vez una mejor manera de hacerlo sería con una función que recibiera el string a analizar, comparar el primer y último caracter: si no, no es; si si, eliminar el primer y último caracter y volver a llamar a la función. Esto hasta que el numero de comparaciones ciertas sea igual a la mitad de la longitud inicial del string. ¿Alguien se anima a hacerlo?

Generar un string aleatorio en C++

No sé, es algo que se me ocurrió y que es muy fácil de hacer. Lo único que tenemos que hacer es ver a un string no como una frase, sino como un conjunto de caracteres; y además ver a los caracteres no como letras, sino números del código ASCII.

Teniendo esto claro, es muy fácil generar un números aleatorios (que representas letras) para llenar cada elemento del arreglo que es nuestro string. Veamos:

#include
#include
#include
using namespace std;

int main()
{
    char strrnd[10];
    srand(time(NULL));
    for(int i=0; i <= 9; i++)
        strrnd[i] = 33 + rand() % (126 - 33);
    cout << strrnd;
    cin.get();
}
  1. Primero declaramos un string de nombre strrnd.
  2. Luego inicializamos nuestro random.
  3. Con un ciclo recorremos cada elemento del string.
  4. Y cada elemento lo llenamos con un número aleatorio entre 33 y 126, que en el código ASCII representan todos las símbolos letras y números normales.
  5. Y listo, ya hemos creado un string aleatorio en c++.

Si tienen duda con los números aleatorios pueden checar este post: Obtener número aleatorios en c++. Aquí pueden ver el código ASCII.

Si quieren que muestre, por ejemplo, solo letras minúsculas, tendrían que modificar la fórmula del random para que generara números entre el 97 y 122.

Como usar cin.getline en C++

Bueno, siguiendo con la línea de los posts sobre la librería string.h les traigo esta función que no está en esa librería pero que es muy útil al trabajar con strings. Ya dijimos que un/una string es una variable que puede contener 0, uno o más caracteres.

Ya vimos en nuestra introducción a string.h cómo declarar un string, hacerle algunas modificaciones y cómo mostrarlo. Ahora veremos como pedir un string (que el usuario la introduzca por medio del teclado).

Esto es muy sencillo si usamos la función cin.getline(); Esta función necesita tres datos o parámetros:

  1. Nombre. El nombre de la variable que va a contener el string
  2. Longitud. La cantidad de caracteres que queremos que se puedan introducir (nunca mayor que la longitud del string).
  3. Caracter de fin. El caracter que el usuario va usar como final de la cadena. Por lo general es el ‘enter‘ que se representa como ‘n’ (diagonal n).

Por ejemplo, supongamos que tenemos un arreglo char de 500 elementos llamado str (nuestra string) y queremos pedirle al usuario que la “llene”, la función cin.getline quedaría así:

cin.getline(str, 500, 'n');

Como ven, los parámetros van separados por comas (,), y el caracter de fin está entre comillas simples (‘). Pero bueno, dejemos de suponer y empecemos a programar.

#include
using namespace std;

int main()
{
    char str[500];
    cout << "Introduce una frase: ";
    cin.getline(str, 500, 'n');
    cout << "Tu frase es: " << str;
    cin.get();
}

Mas sencillo no podría ser.

Introducción a string.h

string.h es una librería de c++ que contiene funciones que nos facilitan la vida al trabajar con cadenas o strings. Una cadena es un conjunto de caracteres almacenados en una variable.

Deberíamos saber que char es un tipo de dato que almacena un caracter, por lo tanto un arreglo lineal de caracteres es una cadena:

char str[100];

Ahora podemos llenar nuestra cadena..

str ="Soy una cadena";

…y mostrarla

cout << str;

Pero recuerden que no podemos hacer nada de esto si no tenemos incluida la librería string.h. Vamos a ver un programa de ejemplo:

#include
#include
using namespace std;

int main()
{
    char esunacadena[100] = "Soy una cadena", esunacopia[100];
    strcpy(esunacopia, esunacadena);
    strcat(esunacopia, " - copia");
    cout << esunacadena << endl << esunacopia;
    cin.get();
    return 0;
}
  1. Primero declaramos dos cadenas (‘esunacadena’ y ‘esunacopia’) que pueden tener hasta 100 caracteres, ‘esunacadena’ la llenamos con el texto “Soy una cadena“.
  2. Luego con la función strcpy copiamos el contenido de ‘esunacadena’ a ‘esunacopia’. Ahora las dos cadenas tienen el mismo texto.
  3. Ahora con la función strcat agregamos el texto ” – copia” al final de’esunacopia’.
  4. Al final solo mostramos las dos cadenas.

Bastante fácil ¿no? En los próximos días voy a postear otros programas muy sencillos para seguir checando las funciones mas comunes para trabajar con cadenas.

Centrar texto automáticamente sin gotoxy

Pues si, en este post vamos a hacer un programa en c++ que lee una frase y luego la muestra centrada en la pantalla, todo eso ¡sin usar gotoxy! wow.

Bueno, usando gotoxy sería mas fácil, pero este blog promueve el no uso de la librería conio.h (Cómo dejar de usar conio.h) así que lo vamos a hacer como les dije.

#include
#include
using namespace std;

int main()
{
    char str[100];
    cout << "Una frase: "; cin.getline(str, 100, 'n');
    int numofch = strlen(str);
    for(int i=1; i<(40-(numofch/2)); i++)
        cout << " ";
    cout << str;
    cin.get();
    return 0;
}

A la consola le caben 80 caracteres a lo largo, su mitad son 40; enseguida tenemos que averiguar el numero de caracteres que tiene la frase que se acaba de introducir y dividirlo entre dos. Supongamos que la frase es “hola”:

  1. ‘Hola’ tiene 4 caracteres.
  2. La mitad de la consola es 40.
  3. Si a los 40 le restamos la mitad de los caracteres de la frase, obtenemos el punto en donde debe comenzar la frase para quedar centrada. 40 – (4/2) = 38
  4. Ahora con un ciclo damos 38 espacios y luego imprimimos la frase.

Si quieren utilizar gotoxy, el proceso es el mismo hasta el último paso, donde guardarían el valor obtenido en una variable y luego lo pondrían en el lugar adecuado de la función.

La función strlen está en la librería string.h y nos devuelve el número de caracteres que tiene una cadena, viene de string length.

A propósito me he dado cuenta que no he hablado casi nada de la librería string.h, voy a ver si hago unos cuantos posts sobre ella.

Como identificar un palíndromo en C++

Lo primero que tendríamos que hacer sería quitar los espacios de nuestra cadena. Luego ir comparando, el primer caracter con el último, el segundo con el penúltimo, etc. Si todos los caracteres coinciden, es palíndromo, si no, pues no.

#include<string.h>
#include<iostream>
using namespace std;

int main()
{
  char cadena[50],cadenaf[50]={0},*parte;
  int c,len,pal=0;
  cout<<"Introduce un palíndromo: "; cin.getline(cadena,50,'n');

  parte=strtok(cadena," ");                  //
  strcat(cadenaf,parte);                    // quita los espacios de 'cadena' y
  while((parte=strtok(NULL," ")) != NULL)  // guarda el resultado en 'cadenaf'
    strcat(cadenaf,parte);                //

  len=strlen(cadenaf);
  for(c=0;c<=len-1;c++)
  {
    if(cadenaf[len-1-c]==cadenaf[c]) // comparación del primer caracter con el
      pal++;                        // último, el segundo con el penúltimo, etc
  }
  if(pal==len) // si todos las caracteres coinciden, sí es palíndromo
    cout<<"Sí es palíndromo!";
  else
    cout<<"No es palíndromo";
  cin.get();
}
/*Creado por THEbatzuk*/

Número de letras y espacios que tiene una frase

Este programa lee una frase por medio de cin.getline y con la función strtrok le quita los espacios. Cada vez que corta la cadena, un contador se aumenta. Al final se obtiene la longitud de la cadena sin espacios con la función strlen.

/*Programa para contabilizar el número de letras y de espacios
que tiene una frase */
#include<iostream>
#include<string.h>
using namespace std;

int main()
{
  char frase[100], *parte, frasef[100]={0};
  int lng,spc=0;
  cout<<"Introduce una frase: "; cin.getline(frase, 100, 'n');
  parte=strtok(frase," ");
  strcat(frasef,parte);
  while((parte=strtok(NULL," ")) != NULL)
  {
    strcat(frasef,parte);
    spc++;
  }
  lng=strlen(frasef);
  cout<<"Tu frase tiene "<<lng<<" letras y "<<spc<<" espacios";
  cin.get();cin.get();
  return 0;
}
/*Creado por THEbatzuk*/