Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Bob1098 en 16 Septiembre 2014, 16:36 pm



Título: Más punteros...
Publicado por: Bob1098 en 16 Septiembre 2014, 16:36 pm
Sigo con el tema de los punteros y sigo sin entender que falla ahora.
Tengo el siguiente ejercicio:

"3.Implementar en una función el siguiente algoritmo para ordenar un array de enteros.
 La idea es recorrer simultáneamente el array desde el principio y desde el final, comparando los elementos. Si los valores comparados no están en el orden adecuado, se intercambian y se vuelve a empezar el bucle. Si están bien ordenados, se compara el siguiente par.
 El proceso termina cuando los punteros se cruzan, ya que eso indica que hemos comparado la primera mitad con la segunda y todos los elementos estaban en el orden correcto.
 Usar una función con tres parámetros:
void Ordenar(int* vector, int nElementos, bool ascendente);
 De nuevo, no se deben usar enteros, sólo punteros y aritmética de punteros."

El problema esta en que los elementos no parecen intercambiarse ni ordenarse, e incluso algunos toman el valor del estilo de -88483432.

Este es mi código:

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. void Ordenar(int*, int, bool);
  6.  
  7. int main() {
  8. int lista[10] = { 1, 4, 2, 5, 3, 7, 6, 9, 8, 10 };
  9.  
  10. for (int i = 0; i <= 9; i++) {
  11. cout << lista[i] << " ";
  12. }
  13. cout << endl;
  14. Ordenar(lista, 10, 0);
  15. for (int i = 0; i <= 9; i++) {
  16. cout << lista[i] << " ";
  17. }
  18.  
  19. cin.sync();
  20. cin.get();
  21. return 0;
  22. }
  23.  
  24. void Ordenar(int *vector, int nElementos, bool ascendente) {
  25. int *q, *p;
  26.  
  27. p = vector;
  28. q = &vector[nElementos];
  29. if (ascendente) {
  30. while (p <= q) {
  31. if (*p > *q) {
  32. *p += *q;
  33. *q = *p - *q;
  34. *p -= *q;
  35. }
  36. p++; q--;
  37. }
  38. }
  39. else {
  40. while (p <= q) {
  41. if (*p < *q) {
  42. *p += *q;
  43. *q = *p - *q;
  44. *p -= *q;
  45. }
  46. p++; q--;
  47. }
  48. }
  49. }
  50.  


Título: Re: Más punteros...
Publicado por: rir3760 en 16 Septiembre 2014, 17:03 pm
El error principal se encuentra en la función "Ordenar", el valor inicial del puntero al ultimo elemento es:
Código
  1. q = &vector[nElementos];
Con eso el puntero "q" apunta a una posición después del ultimo elemento, hay que cambiarlo a:
Código
  1. q = vector + nElementos - 1;

Y el intercambio hay que cambiarlo ya que ignora ciertos detallitos como que sucede si la suma desborda al tipo int (no recuerdo exactamente si es "implementation defined" o "undefined behavior"). Mejor por sencillo:
Código
  1. if (*p > *q){
  2.   int aux;
  3.  
  4.   aux = *p;
  5.   *p = *q;
  6.   *q = aux;
  7. }
  8. p++;
  9. q--;

Por ultimo la condición del bucle debe ser "p < q" ya que no tiene sentido el intercambio si los punteros apuntan al mismo elemento.

Un saludo


Título: Re: Más punteros...
Publicado por: eferion en 16 Septiembre 2014, 17:08 pm
Código
  1. void Ordenar(int*, int, bool);
  2.  
  3. // ...
  4.  
  5. Ordenar(lista, 10, 0);

Los valores válidos para los booleanos son "true" y "false", acostúmbrate a usar esos valores en vez de 1 y 0.

Código
  1. Ordenar(lista, 10, false);

aunque también te puedes plantear el uso de enums:

Código
  1. enum TipoOrden
  2. {
  3.  Ascendente,
  4.  Descendente
  5. };
  6.  
  7. void Ordenar(int *, int , TipoOrden );
  8.  
  9. int main( )
  10. {
  11.  // ...
  12.  Ordenar( lista, 10, Ascendente );
  13.  // ...
  14. }
  15.  
  16. void Ordenar(int *vector, int nElementos, TipoOrden tipoOrden )
  17. {
  18.  // ...
  19.  
  20.  if ( tipoOrden == Ascendente )
  21.  {
  22.  // ...
  23.  


Título: Re: Más punteros...
Publicado por: Bob1098 en 16 Septiembre 2014, 22:35 pm
Vale, ya mas o menos voy entendiendo la función de los punteros. En cuanto a la propuesta de usar valores true o false para los booleanos, es cierto que leí que es mejor usarlos si se tiene oportunidad. También me parece correcto usar un enum, aunque me parece mucha mas simple una variable bool.

*Aún así, sigo sin conseguir el resultado deseado. No parece que el vector se modifique mucho. El resultado en orden ascendente no cambia, y en orden ascendente se queda así: 10  8  9  6  7  3  5  2  4  1.

Gracias una vez más por las respuestas, gracias a este foro se puede aprender y preguntar dudas =).

Un saludo.


Título: Re: Más punteros...
Publicado por: eferion en 17 Septiembre 2014, 11:57 am
*Aún así, sigo sin conseguir el resultado deseado. No parece que el vector se modifique mucho. El resultado en orden ascendente no cambia, y en orden ascendente se queda así: 10  8  9  6  7  3  5  2  4  1.

Eso es porque tu algoritmo de ordenación no funciona.

Te lo pongo con un ejemplo práctico... si tu tienes: 1  4  2  5  3  7  6  9  8  10.

Incialmente comparas 1 y 10... orden correcto, después comparas 4 y 8... orden correcto, después comparas 2 y 9... nuevamente orden correcto... al final no has cambiado ningún valor de posición.

Lo que te están pidiendo es que implementes el algoritmo de la burbuja, el de toda la vida. La "novedad" que plantea tu ejercicio es que tiene que poderse elegir si empiezan por el principio del array o por el final... pero no te están pidiendo que pongas un puntero al principio, otro al final y que vayas comparándolos entre ellos.

No se si me explico.


Título: Re: Más punteros...
Publicado por: Bob1098 en 17 Septiembre 2014, 18:20 pm
Eso es porque tu algoritmo de ordenación no funciona.

Te lo pongo con un ejemplo práctico... si tu tienes: 1  4  2  5  3  7  6  9  8  10.

Incialmente comparas 1 y 10... orden correcto, después comparas 4 y 8... orden correcto, después comparas 2 y 9... nuevamente orden correcto... al final no has cambiado ningún valor de posición.

Lo que te están pidiendo es que implementes el algoritmo de la burbuja, el de toda la vida. La "novedad" que plantea tu ejercicio es que tiene que poderse elegir si empiezan por el principio del array o por el final... pero no te están pidiendo que pongas un puntero al principio, otro al final y que vayas comparándolos entre ellos.

No se si me explico.

Entiendo a lo que te refieres, ya he usado ese algoritmo más de una vez, solo que ahora supongo que si estamos tratando el tema de los punteros pretenden que use punteros en lugar de enteros.

Gracias por la respuesta.