un peu d'aide pour faire des tris

un peu d'aide pour faire des tris - C - Programmation

Marsh Posté le 18-01-2006 à 21:51:17    

Bonjour,
 
j'essaye de comprendre les tris, voilà j'ai fais un petit code afin de manipuler un peu mais apparament c'est correct, si quelqu'un pouvais m'aider a comprendre mes erreurs.
 
 

Code :
  1. int main(int argc, char *argv[])
  2. {
  3. int tableau[5];
  4. int i;
  5. //initialisation du tableau
  6. for(i=0; i<5; i++)
  7. {
  8. printf("saisir un  chiffre\n" );
  9. scanf("%d",&tableau[i]);
  10. }
  11. */
  12. //trie du tableau  
  13.        
  14. for( i=0; i<5; i++);
  15. {
  16.  int temp;
  17.  int *p=&i;
  18.  if(i>i+1)
  19.  {
  20.  *p=temp;
  21.  *p=i+1;
  22.  temp=*p;
  23.  }
  24. // lecture du tableau
  25.        
  26. for(i=0; i<5; i++)
  27. {
  28. printf("%d",tableau[i]);
  29. }
  30. }
  31.        
  32. }

Reply

Marsh Posté le 18-01-2006 à 21:51:17   

Reply

Marsh Posté le 18-01-2006 à 22:34:37    

dodo a écrit :

j'essaye de comprendre les tris,


http://www.cs.ubc.ca/spider/harris [...] -demo.html
 
et forum "algo"

Citation :


voilà j'ai fais un petit code afin de manipuler un peu mais apparament c'est correct, si quelqu'un pouvais m'aider a comprendre mes erreurs.


Qu'est-ce qui est 'correct' ?
De quelles erreurs parles-tu ? Celles-ci ?


Compiling: main.c
main.c: In function `main':
main.c:11: error: implicit declaration of function `printf'
main.c:11: warning: nested extern declaration of `printf'
<internal>:0: warning: redundant redeclaration of 'printf'
main.c:12: error: implicit declaration of function `scanf'
main.c:12: warning: nested extern declaration of `scanf'
<internal>:0: warning: redundant redeclaration of 'scanf'
main.c:16: error: syntax error before '/' token
main.c:21: error: syntax error before ')' token
main.c:39: warning: nested extern declaration of `printf'
<internal>:0: warning: redundant redeclaration of 'printf'
main.c:21: warning: statement with no effect
Process terminated with status 1 (0 minutes, 0 seconds)


Commentaires (-ed-) :  


/* -ed- manquait pour printf() */
#include <stdio.h>
 
int main(int argc, char *argv[])
{
   int tableau[5];
   int i;
 
   //initialisation du tableau
   for (i = 0; i < 5; i++)
   {
      printf("saisir un nombre\n" );
      scanf("%d", tableau + i);
   }
 
 
   //tri du tableau
   for ( i = 0; i < 5; i++)
      /* -ed-
            ;
 
      en trop...
      */
   {
      int temp;
      int *p = &i;
 
      if (i > i + 1)
         /* -ed- ca ne risque pas d'arriver. Visiblement ton algo est faux.
                 Ca ne sert a rien de bricoler. Il faut commencer par avoir  
                 un algo correct. Il ne manque pas de livres et de sites sur  
                 le sujet...  
                 */
      {
         *p = temp;
         *p = i + 1;
         temp = *p;
      }
      /* -ed- si c'est cense etre le tri bulle, il en manque... */
   }
 
   /* -ed- deplace. Etait dans la boucle (debug ?) */
   // lecture du tableau
   for (i = 0; i < 5; i++)
   {
      printf("%d", tableau[i]);
   }
 
   /* -ed- ajoute */
   return 0;
}

Message cité 1 fois
Message édité par Emmanuel Delahaye le 18-01-2006 à 23:30:59

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-01-2006 à 22:37:04    

je vois mal les codes (d'ailleurs je sais pas pourquoi ...bref [:pingouino])
Mais est ce qu'il ne devrait pas (en plsu du reste ) fermer la boucle de for du tri avant celle de l'affichage?
 
oula j'avais pas vu le reste.
Effectivement, forum "algo".
Indic : pour ton tri tu fais ca avec la variable i et non avec ton tableau...c'est dommage :)

Message cité 1 fois
Message édité par gocho le 18-01-2006 à 22:38:45
Reply

Marsh Posté le 18-01-2006 à 22:46:12    

salut,
j'ai pas trop compris ce que fait le */ sans le /* qui va avec, mais ça doit être une erreur de copier coller ...
sinon, je te conseille FORTEMENT de mettre un commentaire associé à chaque accolade, pour dire à quel début ou quelle fin de boucle elle correspond !!! tu verras que ce que tu fais est un peu bizarre
Sinon, pour déclarer un ponteur, * correspond au déférencement Il ne faut donc pas mattre le & devant i, sauf si tu veux un  pointeur de pointeur
tu peux faire plutôt :
int *p;
p = &i;
 
ou :
int *p = i;
 
je ne comprend pas très bien le scanf avec le &tableau... il vaut mieux je pense mettre * ou rien
je crois de plus que tu confond l'adresse de i et l'addresse de tableau[i]...
 
mais te prend surtout pas la tête avec les pointeur pour un simple tableau !!!
non seulement c'est inutile en soit, mais en plus, pour les tableaux toujours, le C travaille automatiquement avec les adresses des éléments

Message cité 1 fois
Message édité par jimipage le 18-01-2006 à 22:49:49

---------------
un perlien qui programme salement
Reply

Marsh Posté le 18-01-2006 à 22:48:43    

jimipage a écrit :


Sinon, pour déclarer un ponteur, * correspond au déférencement (la varaible p est un pointeur, *p est la valeur qui de la variable sur laquelle le pointeur pointe. Il ne faut donc pas mattre le &
tu peux faire plutôt :
int *p;
p = &i;
 
ou :
int *p = i;
 
je ne comprend pas très bien le scanf avec le &tableau... il vaut mieux je pense mettre * ou rien
je crois de plus que tu confond l'adresse de i et l'addresse de tableau[i]...
 
mais te prend surtout pas la tête avec les pointeur pour un simple tableau !!!
non seulement c'est inutile en soit, mais en plus, pour les tableaux toujours, le C travaille automatiquement avec les adresses des éléments


T'as fini de raconter n'importe quoi...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-01-2006 à 22:52:00    

Emmanuel Delahaye a écrit :

http://www.cs.ubc.ca/spider/harris [...] -demo.html
 
et forum "algo"

Citation :


voilà j'ai fais un petit code afin de manipuler un peu mais apparament c'est correct, si quelqu'un pouvais m'aider a comprendre mes erreurs.


Ques-ce qui est 'correct' ?
De quelles erreurs parles-tu ? Celles-ci ?


Compiling: main.c
main.c: In function `main':
main.c:11: error: implicit declaration of function `printf'
main.c:11: warning: nested extern declaration of `printf'
<internal>:0: warning: redundant redeclaration of 'printf'
main.c:12: error: implicit declaration of function `scanf'
main.c:12: warning: nested extern declaration of `scanf'
<internal>:0: warning: redundant redeclaration of 'scanf'
main.c:16: error: syntax error before '/' token
main.c:21: error: syntax error before ')' token
main.c:39: warning: nested extern declaration of `printf'
<internal>:0: warning: redundant redeclaration of 'printf'
main.c:21: warning: statement with no effect
Process terminated with status 1 (0 minutes, 0 seconds)


Commentaires (-ed-) :  


/* -ed- manquait pour printf() */
#include <stdio.h>
 
int main(int argc, char *argv[])
{
   int tableau[5];
   int i;
 
   //initialisation du tableau
   for (i = 0; i < 5; i++)
   {
      printf("saisir un nombre\n" );
      scanf("%d", tableau + i);
   }
 
 
   //tri du tableau
   for ( i = 0; i < 5; i++)
      /* -ed-
            ;
 
      en trop...
      */
   {
      int temp;
      int *p = &i;
 
      if (i > i + 1)
         /* -ed- ca ne risque pas d'arriver. Visiblement ton algo est faux.
                 Ca ne sert a rien de bricoler. Il faut commencer par avoir  
                 un algo correct. Il ne manque pas de livres et de sites sur  
                 le sujet...  
                 */
      {
         *p = temp;
         *p = i + 1;
         temp = *p;
      }
      /* -ed- si c'est cense etre le tri bulle, il en manque... */
   }
 
   /* -ed- deplace. Etait dans la boucle (debug ?) */
   // lecture du tableau
   for (i = 0; i < 5; i++)
   {
      printf("%d", tableau[i]);
   }
 
   /* -ed- ajoute */
   return 0;
}



 
 
oups!!! :kaola:  mon compilateur me donne pas ces erreurs!!!

Reply

Marsh Posté le 18-01-2006 à 22:55:05    

Emmanuel Delahaye a écrit :

T'as fini de raconter n'importe quoi...


 
A ce point ? :ouch: ?


---------------
un perlien qui programme salement
Reply

Marsh Posté le 18-01-2006 à 22:55:39    

gocho a écrit :

je vois mal les codes (d'ailleurs je sais pas pourquoi ...bref [:pingouino])
Mais est ce qu'il ne devrait pas (en plsu du reste ) fermer la boucle de for du tri avant celle de l'affichage?
 
oula j'avais pas vu le reste.
Effectivement, forum "algo".
Indic : pour ton tri tu fais ca avec la variable i et non avec ton tableau...c'est dommage :)


 
 
En faite, c'était ma première idée de travailler le trie avec les tableaux.

Reply

Marsh Posté le 18-01-2006 à 23:01:59    

ouai bon désolé pour le scanf j'suis fatigué
 
mais pour le int *p = i;    je vois pas trop le pb
 
à moins de vouloir faire un pointeur de pointeur avec *p = &i;


---------------
un perlien qui programme salement
Reply

Marsh Posté le 18-01-2006 à 23:28:23    

dodo a écrit :

oups!!! :kaola:  mon compilateur me donne pas ces erreurs!!!


Avec gcc j'utilise au moins ceci :  

-Wall -Wextra (ou -W si trop vieux) -O2


et si je fais du standard pur, j'ajoute :  

-ansi -pedantic



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-01-2006 à 23:28:23   

Reply

Marsh Posté le 18-01-2006 à 23:30:02    

jimipage a écrit :

mais pour le int *p = i;    je vois pas trop le pb


Si i est un int comme son nom le laisse supposer ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-01-2006 à 23:30:45    

Sinon, pour le tri en général ya une page très bien sur la wikipedia :o


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 19-01-2006 à 08:10:40    

jimipage a écrit :

mais pour le int *p = i;    je vois pas trop le pb


 
"i" est de type "int". Tu peux pas le mettre dans "p" qui est de type "int étoile".
"&i" est de type "int étoile" donc tu peux le mettre dans "p" => "int *p=&i".


Message édité par Sve@r le 19-01-2006 à 08:11:17

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 19-01-2006 à 21:49:28    

ça a l'air de marcher comme ça
 
(pour les commentaires, je préfère m'abstenir que de dire des âneries) :D
 

Code :
  1. #include <stdio.h>
  2. int main(int argc, char *argv[])
  3. {
  4. int tableau[5];
  5. int i , j, k , temp;
  6. int *p , *q;
  7. //initialisation du tableau
  8. for(i=0; i<5; i++)
  9. {
  10. printf("saisir un  chiffre\n" );
  11. scanf("%d",&tableau[i]);
  12. }
  13. //tri du tableau  
  14.        
  15. for (i = 0 ; i < 5 ; i++) {
  16. for (j = 0 ; j < 4 ; j++) {
  17.  p = &tableau[j];
  18.  q = &tableau[j+1];
  19.  if(*p > *q)
  20.  {
  21.  temp = *p;
  22.  *p = *q;
  23.  *q = temp;
  24.  }
  25.  }}
  26. // lecture du tableau
  27.        
  28. for(i=0; i<5; i++)
  29. {
  30. printf("%d",tableau[i]);
  31. }
  32. }

Reply

Marsh Posté le 19-01-2006 à 22:04:43    

rem : k ne sert à rien, et on peut faire un for (i = 0 ; i < 4 ; i++)

Reply

Marsh Posté le 20-01-2006 à 22:59:58    

jimipage a écrit :

ça a l'air de marcher comme ça
 
(pour les commentaires, je préfère m'abstenir que de dire des âneries) :D
 

Code :
  1. #include <stdio.h>
  2. int main(int argc, char *argv[])
  3. {
  4. int tableau[5];
  5. int i , j, k , temp;
  6. int *p , *q;
  7. //initialisation du tableau
  8. for(i=0; i<5; i++)
  9. {
  10. printf("saisir un  chiffre\n" );
  11. scanf("%d",&tableau[i]);
  12. }
  13. //tri du tableau  
  14.        
  15. for (i = 0 ; i < 5 ; i++) {
  16. for (j = 0 ; j < 4 ; j++) {
  17.  p = &tableau[j];
  18.  q = &tableau[j+1];
  19.  if(*p > *q)
  20.  {
  21.  temp = *p;
  22.  *p = *q;
  23.  *q = temp;
  24.  }
  25.  }}
  26. // lecture du tableau
  27.        
  28. for(i=0; i<5; i++)
  29. {
  30. printf("%d",tableau[i]);
  31. }
  32. }



 
Moi, je crois au contraire que tu devrais mettre des commentaires justement pour qu'on voit si tu comprends bien ce que tu fais. Mais sinon, effectivement, il n'y a aucune erreur de C (j'ai pas regardé l'algo mais lui-aussi semble correct). Et utiliser deux pointeurs est une bonne idée, ça te permet de t'habituer à travailler avec.
 
Petit truc amusant: on peut très bien permuter deux valeurs "a" et "b" sans passer par "temp" en utilisant juste le XOR
a=a^b;
b=a^b;
a=a^b;
Et voilà... ça marche sauf si "a" ou "b" sont des pointeurs qui pointent tous deux vers la même variable.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 21-01-2006 à 01:05:58    

Sve@r a écrit :

Moi, je crois au contraire que tu devrais mettre des commentaires justement pour qu'on voit si tu comprends bien ce que tu fais.


 
Bon bé allons-y, je vais essayer de me concentrer... ce qui commence à être quelque peu laborieux  [:kombak]
 

Code :
  1. #include <stdio.h>
  2. int main(int argc, char *argv[])
  3. {
  4. int tableau[5]; // déclaration du tableau d'entiers. les indices vont de 0 à 4
  5. int i , j , temp; // déclaration des 2 variables d'itérations et d'une variable servant d'intermédiaire dans l'algorithme
  6. int *p , *q; // déclaration de 2 pointeurs, pointant vers des valeurs de type int
  7. //initialisation du tableau
  8. for(i=0; i<5; i++)
  9. {
  10. printf("saisir un  chiffre\n" );
  11. scanf("%d",&tableau[i]);
  12. }
  13. //tri du tableau  
  14.        
  15. /*
  16. 2 boucles encastrées sont nécessaires.
  17. en effet, prenons le cas extrème où on part de :
  18. tableau[0] == 5
  19. tableau[1] == 4
  20. tableau[2] == 3
  21. tableau[3] == 2
  22. tableau[4] == 1
  23. dans la première boucle effectuée sur j, on obtient :
  24. pour j==0 : inversion des valeurs de tableau[0] et tableau[1]  
  25. pour j==1 : inversion des valeurs de tableau[1] et tableau[2]
  26. etc...
  27. et on se retrouve avec les valeurs dans l'ordre : 43215
  28. ainsi, la variable i ne sert à rien d'autre qu'à répéter la boucle sur j,
  29. pour ensuite placer 4 au bon endroit, puis 3, puis 2
  30. là normalement 1 se retrouve bien placé aussi, d'où 4 boucles seulement sur j  
  31. (puisque toutes les autres valeurs sont bien placées, 1 ne peut aller qu'à la bonne place aussi)
  32. */
  33. for (i = 0 ; i < 4 ; i++) {
  34. for (j = 0 ; j < 4 ; j++) {
  35.  p = &tableau[j]; // on assigne à p l'adresse de tableau[j]
  36.  q = &tableau[j+1];  // on assigne à q l'adresse de tableau[j+1]
  37. // on a du coup 2 pointeurs, auxquelles on assigne les adresses des valeurs à comparer
  38.  if(*p > *q) // test pour savoir si il faut effectuer une inversion
  39.  {
  40.  temp = *p;  // temp prend la valeur de tableau[i]
  41.  *p = *q;  // tableau[i] prend la valeur de tableau[i+1]
  42.  *q = temp;  // tableau[i+1] prend l'ancienne valeur de tableau[i]
  43.  }
  44.  }}
  45. // lecture du tableau
  46.        
  47. for(i=0; i<5; i++)
  48. {
  49. printf("%d",tableau[i]);
  50. }
  51. }


Message édité par jimipage le 21-01-2006 à 01:07:08
Reply

Marsh Posté le 21-01-2006 à 01:21:43    

Sve@r a écrit :

Moi, je crois au contraire que tu devrais mettre des commentaires justement pour qu'on voit si tu comprends bien ce que tu fais.


 
Une bonne idée les commentaires, vu qu'on voit qu'il n'est pas nécessaire d'aller jusqu'au bout à chaque fois :
quand le 5 est bien placé, ça ne sert à rien de refaire le test
idem quand le 4 est bien placé...
 
d'où la solution suivante, plus rapide car n'effectuant pas tous ces tests forcément inutiles :
 
for (i = 3 ; i >= 0 ; i--) {
for (j = 0 ; j <= i ; j++) {
// traitement
}}
 
du coup i nous dit jusqu'où il faut encore aller

Reply

Marsh Posté le 21-01-2006 à 08:12:17    

jimipage a écrit :

Une bonne idée les commentaires


Oui... mais pas forcément un par ligne  :)  

jimipage a écrit :

vu qu'on voit qu'il n'est pas nécessaire d'aller jusqu'au bout à chaque fois :
quand le 5 est bien placé, ça ne sert à rien de refaire le test
idem quand le 4 est bien placé...
 
d'où la solution suivante, plus rapide car n'effectuant pas tous ces tests forcément inutiles :
 
for (i = 3 ; i >= 0 ; i--) {
for (j = 0 ; j <= i ; j++) {
// traitement
}}
 
du coup i nous dit jusqu'où il faut encore aller


Tu es en train de nous réinventer l'algo du tri à bulle optimisé où on mémorise la position du 1er élément mal placé pour ne recommencer qu'à partir de ce point lors de la boucle suivante
Début=2° position  // L'indice "1" est celui de la 2° position
Fin=dernière position
Faire
     Flag=0
     Pour i partant du début jusqu'à la Fin
     Faire
            Si elem[i - 1] > elem[i]
            alors
                  permuter elem[i - 1] et elem[i]
                  si flag = 0
                  alors
                        debut=i   // Mémorise la position du 1er élément incorrect
                        flag=1
                  fin si
            fin si
      fin faire
      Fin=Fin - 1    // Le dernier élément est forcément bien placé
tant que flag = 1  // on recommence tant que un élément incorrect
 
Dans le pire des cas, cet algo fait autant de boucles que le tien. Dans le meilleur, il n'en fait qu'une seule


Message édité par Sve@r le 21-01-2006 à 08:28:22

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed