ejercicio en C

Iniciado por howaboutno, 30 Octubre 2012, 19:53 PM

0 Miembros y 1 Visitante están viendo este tema.

howaboutno

hola, me estoy atascando de nuevo....
Hacer un programa para que dada una palabra de no mas de 20 caracteres  y efectúe todas las rotaciones posibles de dicha palabra de forma que el último carácter pase al primero y los demás corran un espacio, es decir si la palabra fuera "HOLA"  el resultado debe ser :
HOLA
AHOL
LAHO
OLAH

claro, llego hasta el punto de recorrer la cadena pero luego es que no hay funcion alguna para eso... eso, que lo que no tengo claro como hacer correr un espacio el caracter... ideas? sugerencias? pistas?
gracias =)

lapras

#1
Así es como yo lo haría.

#include <stdio.h>

int cnoc(char*);
void rotate(char*);

int main(){
char cad[256]={};
scanf("%s",cad);
printf("length=%20s\n", cad); //NOTA: cuidado con el buffer overflow(printf("length=%s\n", cad);)
int n=cnoc(cad);


int i;
for(i=0; i<n; i++){ //rotar n veces. Así conseguimos todas las combinaciones posibles
rotate(cad);
printf("%s\n", cad);
}
}


int cnoc(char cad[]){  // Devuelve el número de caracteres en una cadena
int i=0;
while(cad[i]) i++;
return i;
}

void rotate(char cad[]){ //rotar la cadena 1 posición
int n=cnoc(cad)-1; //n apunta a la untima posición
char last= cad[n--]; //guardamos el valor de la ultima posición en variable last
for(;n>=0;n--) cad[n+1]=cad[n]; //desplazamos todos los caracteres una posición hacia delante
cad[0]=last; //como el primer elemento no tiene precedente tenemos que==>
// ==>poner en él el que fue el el último
}

EDIT: añado comentarios

leosansan

#2
CitarEspero que te sea útil. Prueba lo con números que es más visual la rotación:
Código (cpp) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   int i,j=0,k;
   char cadena [80];
   gets (cadena);
   k=strlen (cadena);
   puts("\n");
   while (k>=1)
           {
               for (i=k;i<=strlen (cadena);i++)
                   printf ("%c",cadena[i]);
               printf ("\b");
               for (j=0;j<k  ;j++)
                       printf ("%c",cadena[j]);
               j++;k--;puts("\n");
           }
   return 0;
}

Saludos!.

lapras

#3
Me mola tu código leosansan.
Por cierto, ¿para que pones printf("\b")? ¿es por que te sale algún carácter raro?
Lo digo por que me suena que en algunas plataformas el carácter nulo es imprimible y tu codigo accede al ultimo caracter de la string (NULL) y lo imprime.
Yo  que estoy en linux, tu código imprime esto:
Código (bash) [Seleccionar]
tuket@debian:~$ ./a.out
hole


hol

lho

olh


Parece que en linux no se imprime el carácter nulo entonces al borrar se queda con una letra menos. Tal vez el remedio sería no imprimir ese carácter para no tener que borrarlo.

k=strlen (cadena)-1;
for (i=k;i<strlen (cadena);i++)
.
Simplemente modificando esas dos líneas

xiruko

#4
te dejo una solucion que quizas es algo confusa, aunque a mi me ha ido bien para repasar aritmetica de punteros:

#include <stdio.h>
#include <string.h>
#define MAX 64

int main() {

char cadena[MAX];
int i, longitud;

printf("Introduce la cadena: ");
fgets(cadena, MAX-1, stdin);
longitud=strlen(cadena);
cadena[longitud-1]='\0';
longitud--;

for (i=0; i<longitud; i++) {
printf("%s%s\n", cadena+longitud-i+1, cadena);
cadena[longitud-i]=cadena[longitud-1-i];
cadena[longitud-1-i]='\0';
}

return 0;
}


la salida:

xiruko:~$ gcc rotar.c -o rotar
xiruko:~$ ./rotar
Introduce la cadena: hola
hola
ahol
laho
olah
xiruko:~$


un saludo!

lapras


rir3760

Otra forma consiste en indicar el numero de caracteres a imprimir mediante "%.*s" en la llamada a "printf":
#include <stdio.h>

int main (void)
{
   char cad[] = "hola";
   size_t nc = sizeof cad - 1;
   size_t i;
   
   puts(cad);
   for (i = 1; i < nc; i++)
      printf("%s%.*s\n", cad + nc - i, nc - i, cad);
   
   return 0;
}


Un saludo
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

leosansan

Cita de: tuket en 31 Octubre 2012, 00:14 AM
Me mola tu código leosansan.
Por cierto, ¿para que pones printf("\b")? ¿es por que te sale algún carácter raro?
En W7 sale un espacio en blanco después de imprimir los primeros caracteres, por eso tengo que eliminarlo. Por lo que comentas, en Linux no sucede eso, por lo que podrías eliminarlo.

xiruko

CitarOtra forma consiste en indicar el numero de caracteres a imprimir mediante "%.*s" en la llamada a "printf":
#include <stdio.h>

int main (void)
{
  char cad[] = "hola";
  size_t nc = sizeof cad - 1;
  size_t i;

  puts(cad);
  for (i = 1; i < nc; i++)
     printf("%s%.*s\n", cad + nc - i, nc - i, cad);

  return 0;
}


joder rir3760, siempre posteas codigos mucho mas simples que los mios usando "trucos" como en este caso esto del printf() xD

donde has aprendido esto por ejemplo? podrias recomendarme algun libro o web que no sea de iniciacion en C sino que profundice mas?

en cuanto a tu codigo, me ha gustado sobretodo lo de usar sizeof para saber el tamaño de la cadena, no lo habia pensado y asi me evitaria incluir la libreria string en el codigo. en fin... gracias por todo y a ver si puedes recomendarme algo :rolleyes:

un saludo!

lapras

Lo bueno que tiene el código de rir3760 es que no hace ningún cambio en la cadena. Es genial.