Vectores: Rotación (a la derecha)

Si eres principiante y tienes alguna consulta entra en este foro.
Responder
Mensaje
Autor
Anon
Mensajes: 15
Registrado: 07/03/2013 12:00 pm

Vectores: Rotación (a la derecha)

#1 Mensaje por Anon » 10/04/2013 2:39 am

El programa tiene que hacer rotar los números introducidos, un puesto a la derecha, excepto el último, que pasara a primer lugar.

El código que he hecho es el siguiente, aunque es incorrecto:

Código: Seleccionar todo

#include <stdio.h>
#include <stdlib.h>
#define X 5

void leer_secuencia (int * secuencia, int N)

{
	
	int j;
	
	for (j=0; j<N; j++)
	
	{
		printf ("Introduce numero: ");
		
		scanf ("%i", &secuencia[j]);
	
	}

}

void rotar_secuencia (int * secuencia, int N)

{
	int i=0, aux;
	for (; i<N; i++)

	{

		if (i<N-1) 
		
		{
			
			aux=secuencia[i+1];
			
			secuencia[i+1]=secuencia[i+2];
			
			secuencia[i]=aux;
		
		}

		else secuencia[i]=secuencia[i-i];
	
	}
}

void printar_secuencia (int * secuencia, int N)

{
	
	int k;
	
	for (k=0; k<N; k++)
	
	{
		
		printf ("%i ", secuencia[k]);
	
	}

}


int main()

{
	
	int secuencia[X];
	
	leer_secuencia (secuencia, X);
	
	rotar_secuencia (secuencia, X);
	
	printar_secuencia (secuencia, X);
	
	printf ("\n");
	
	system("PAUSE");
	
	return 0;

}
Sé que el error esta en el procedimiento rotar_secuencia, pero no logro hallar el procedimiento adecuado.

Pantalàimon_
Mensajes: 1345
Registrado: 17/07/2007 2:38 am

#2 Mensaje por Pantalàimon_ » 10/04/2013 3:52 am

En tu programa si i == N-2, el if dentro del for es cierto y por tanto se ejecutará la sentencia:

Código: Seleccionar todo

secuencia[ N-1 ] = secuencia[N];
Piensa que los elementos de un array de N elementos toman los índices de 0 a N-1. Con lo cual accedes a un valor fuera del rango permitido.

De todos modos aux sólo hace falta usarlo una vez y no N veces. Por ejemplo, guardas en aux el valor del ultimo elemento( secuencia[N-1] ).
Luego en orden descendente de N-1 a 2, asignas a los elementos su elemento anterior. Es muy importante el orden descendente para no perder los valores.
Y por último el valor del último elemento guardado en aux para que no se perdiera lo asignas al primero( secuencia[0] ).

Un saludo!

Anon
Mensajes: 15
Registrado: 07/03/2013 12:00 pm

#3 Mensaje por Anon » 10/04/2013 9:03 am

No he entendido tu explicación, pero gracias igualmente.

Pantalàimon_
Mensajes: 1345
Registrado: 17/07/2007 2:38 am

#4 Mensaje por Pantalàimon_ » 10/04/2013 11:10 am

¿No entiendes el error que te he comentado en tu código o la solución alternativa que te he propuesto?

Sobre el error en tú código, ¿entiendes que si tienes un array de N elementos accedes a esos elementos con índices entre 0 y N-1?

¿ entiendes que dentro de este for i tomará valores entre 0 y N-1 ?

Código: Seleccionar todo

  int i=0, aux; 
   for (; i<N; i++) 

   { 
      /* etc */
   
   }
Si entiendes eso, entenderás que i+1 tomará valores entre 1 y N e i+2 tomará valores entre 2 y N+1.

Parece que pones un if protector en tu código para que no se ejecute este código:

Código: Seleccionar todo

         aux=secuencia[i+1]; 
          
         secuencia[i+1]=secuencia[i+2]; 
          
         secuencia[i]=aux; 
cuando "i" sea más grande o igual a N-1.

Pero es que cuando i valga N-2, i+2 valdrá N. Con lo cual estarás accediendo a un elemento fuera del rango del array secuencia.

Sobre la solución alternativa, he cometido un error. Sería:
1) Guardar en aux el valor del ultimo elemento de secuencia.
2) Asignar a los elementos de N-2 a 1 de secuencia sus elementos anteriores de forma descendente.
3) Asignar al primer elemento de secuencia el valor de aux.

Te pongo el código sin usar for. Creo que poner el for adecuado para que funcione para un número arbitrario de elementos deberías hacerlo tú:

Código: Seleccionar todo

void rotar_secuencia (int * secuencia, int N) 
{ 
   int i=0, aux; 

/* 1) Guardar en aux el valor del ultimo elemento de secuencia */
   aux = secuencia[4];

/* 2) asignar a los elementos de N-2 a 0 sus **
   ** elementos anteriores descendentemente  */ 
   secuencia[4] = secuencia[3];
   secuencia[3] = secuencia[2];
   secuencia[2] = secuencia[1];
   secuencia[1] = secuencia[0];

/* 3) Asignar al primer elemento de secuencia el valor de aux */
   secuencia[0] = aux;
} 
Un saludo!

Anon
Mensajes: 15
Registrado: 07/03/2013 12:00 pm

#5 Mensaje por Anon » 11/04/2013 12:03 pm

¡Gracias por la ayuda!

Al final, el código resultante ha sido:

Código: Seleccionar todo

void rotar_secuencia (int * secuencia, int N)
{
     int i, aux=0;
     
     aux=secuencia[N-1];
     for (i=2; N-i>=0; i++) secuencia[N-i+1]=secuencia[N-i];
     secuencia[0]=aux;     
}
Saludos!

Avatar de Usuario
rir3760
Mensajes: 7553
Registrado: 01/10/2004 11:00 pm
Ubicación: Mexico

#6 Mensaje por rir3760 » 11/04/2013 4:53 pm

Otra forma de implementar el bucle es utilizando el segundo parámetro (N, numero de elementos) como su contador:

Código: Seleccionar todo

void rotar_secuencia(int *secuencia, int N)
{
   int aux = secuencia[N - 1];
   
   while (--N > 0)
      secuencia[N] = secuencia[N - 1];
   
   secuencia[N] = aux;
}
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

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 10 invitados