[C] Tableau à deux dimensions

Tableau à deux dimensions [C] - C - Programmation

Marsh Posté le 06-12-2007 à 00:32:56    

Bonsoir,
je vous explique mon problème, je suis entrain de réaliser un programme dans le quel l'opérateur va rentrer deux valeurs qui correspondent aux nombres de lignes du tableau et aux nombres de colonnes, aussi je dois reinitialiser le tableau en mettant des 0 partout.  
 
Je ne sais donc pas comment modifier la taille des lignes et des colonnes du tableau dans le programme en fonction de n et m...
 
Actuellement j'ai ça :
 

Citation :


int **tab;
 
tab = malloc(n*sizeof(int));
for (i=0;i<n;i++)
{
_____tab[i] = malloc(m*sizeof(int));
_____for (j=0;j<n;j++)
_____{
__________tab[i][j]=0;
__________//printf("%d",tab[i][j]);
_____}
}


 
si vous pouviez m'aider ça serait super !
 
Merci beaucoup
 
P.S: Si vous n'avez pas compris ce que je souhaite faites le moi savoir  :pt1cable:


Message édité par yokooo le 06-12-2007 à 01:54:49
Reply

Marsh Posté le 06-12-2007 à 00:32:56   

Reply

Marsh Posté le 06-12-2007 à 03:36:12    

Oué, presque bon. Dans ta boucle sur j, j'itérerai jusqu'à m et non n.
 
Sinon plus hardcore, tu alloues ta matrice d'un bloc et tu retrouves l'indice i, j en faisant : i * m + j. Du coup tu pourras l'initialiser avec un appel à memset et surtout libérer la mémoire avec un seul free (ce qui en C, n'est pas du luxe).
 
Et si tu veux vraiment faire dans l'ultra hard core, en plus de ta matrice, tu te réserves n pointeurs sur (int *), que tu feras pointer sur le début de chaque lignes de ta matrice. Du coup :
* initialisation à 0 avec un memset
* possibilité d'accéder à un élément via tab[i][j] plutôt que tab[i * m + j]
* Libération avec un seul free.

Message cité 1 fois
Message édité par tpierron le 06-12-2007 à 03:37:34
Reply

Marsh Posté le 06-12-2007 à 06:22:54    

tpierron a écrit :

Dans ta boucle sur j, j'itérerai jusqu'à m et non n.


alalaaa le copié-collé ça joue des tours ...
merci je n'avais pas remarqué ! :)
 
bon je vais essayé toutes ces modifs !

Reply

Marsh Posté le 06-12-2007 à 09:00:52    

@tpierron:
Le modéle H*W + acces en i+j*h est extrement peu performant.
Il est plus efficace et plus simple d'allouer un tableau 1D de H*W éléments puis de l'attaquer avec un tableau de pointeur de H éléments, chacun pointant sur le début d ela colonne correspondante.

Message cité 1 fois
Message édité par Joel F le 06-12-2007 à 09:01:35
Reply

Marsh Posté le 06-12-2007 à 12:25:13    

Joel F a écrit :

Le modéle H*W + acces en i+j*h est extrement peu performant.


Qu'est-ce qui te fais dire ça ? Je pense que dans la pluspart des cas allouer un bloc mémoire et calculer les offsets sera au contraire plus rapide qu'allouer n blocs, et aller déréférencer une adresse à chaque accès.

Reply

Marsh Posté le 06-12-2007 à 12:32:06    

tu veut creer un tableau HxW :
tu alloue un bloc de HxW elements
tu allour un tablea de H pointeurs
tu remplis ce tableau avec les offsets de colonnes.

 

Moralité :
tu accédes en T[i][j]
tu n'as qu'un bloc contigue (bon pr le cache)

 

Et ce qui me fait dire ça : ma thése sur le sujet + 2 ans de travaux en Traitement d'images haute performances :o

 

Le truc A NE PAS FAIRE : allouer un tableau de pointeur et allouer W pointeur differents discontinues

Message cité 1 fois
Message édité par Joel F le 06-12-2007 à 12:33:01
Reply

Marsh Posté le 06-12-2007 à 20:26:00    

il est possible d'optimiser le calcul de produit de matrices en transposant la deuxieme matrice !
Le gain en performance est assez interessant pour des grosses matrices mais pas pour des petites matrices


Message édité par neg'gwada le 07-12-2007 à 21:23:34

---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 06-12-2007 à 20:38:01    

transposition matrice NxM = NxM load + NxM store ....
le gain devient bon quand le gain du à la localité dans le cache devient superieure à 2NM donc ?

Reply

Marsh Posté le 06-12-2007 à 22:17:38    

Qu'est-ce qui pose problème dans le fait d'allouer plusieurs pointeurs (pour chaque ligne) sur plusieurs emplacements mémoire discontinus?

Reply

Marsh Posté le 06-12-2007 à 22:23:00    

si tes empalcements sont discontinu, tu va pourrir ton cache à chaque fin de ligne. Si ton bloc est continu (et que tu fais un beau tiling) tu mlinimises les sorties de cache.
 
et ca c'ets bien pour la planète :o

Reply

Marsh Posté le 06-12-2007 à 22:23:00   

Reply

Marsh Posté le 06-12-2007 à 22:25:14    

C'est quoi le cache et le tiling? Le cache c'est la mémoire cache du proc?

Reply

Marsh Posté le 06-12-2007 à 22:37:03    

oui. le tiling c'est une technique qui consiste à travailler non pas sur les elements de ton tableau un par un mais par groupe de zone polygonale.

 

En general tu ecris

 
Code :
  1. for(int i=0;i<N;i++)
  2. for(int j=0;j<N;j++)
  3.   tab[i][j] = ...
 

c'ets - bon que :

 
Code :
  1. for(int ti=0;ti<N/8;ti++)
  2. for(int tj=0;tj<N/8;tj++)
  3.   for(int i=ti*8;i<(ti+1)*8;i++)
  4.    for(int j=tj*8;j<(tj+1)*8;j++)
  5.     tab[i][j] = ...
 

Dans le 2e cas, tu maximise la localité de tes données dans le cache et limite les cache miss. On démotnre (enfin les matheux démontre) que la forme de tile optimale ets une bouel carrée, donc ici un rectangle ou un carré.

 

La j'ai ecris à la va-vite. LE vrai code ne fait pas de *8 masi juste des += 8


Message édité par Joel F le 06-12-2007 à 22:43:00
Reply

Marsh Posté le 06-12-2007 à 23:40:24    

Je suis pas sûr de bien avoir compris comment tu procèdes Joel. T c'est le tableau de H pointeurs, c'est ça ? Dans ce cas pour accéder à T[i][j] tu va d'abord lire l'adresse en T[i] (l'adresse de ta colonne), puis ensuite la valeur à cette adresse + j ? Comment ça peux être plus rapide qu'aller simplement lire la valeur à l'adresse B + H*i+j où B est ton bloc de H*W éléments (bloc contigu dans les deux cas) ? Surtout que la plupart des proc on un instruction qui fait mul et add en un coup ?

Reply

Marsh Posté le 06-12-2007 à 23:59:41    

bon pour vous expliquer j'ai un projet à réaliser, le sujet est le suivant :
j'ai une blatte qui se trouve sur du carrelage aux dimensions de n x m (défini par l'utilisateur).
Le but est d'afficher lorsque la blatte est passée 3 fois sur chacun des carreaux. au bout de 50 000 déplacement la blatte s'arrete et on renvoi un message qui indique que les test n'a pas été réalisé.  
Voila ce que j'ai fait... cependant des erreurs subsistent...
Pourriez vous m'aider ? Merci


Message édité par yokooo le 07-12-2007 à 17:59:20
Reply

Marsh Posté le 07-12-2007 à 02:35:19    

Deja, cette partie la:

Citation :

while((imove[r]+ibug<0) || (jmove[r]+jbug<0) || (imove[r]+ibug>=n) || (jmove[r]+jbug>=m))  
      {  
          srand(time(NULL));  
          r = (rand() % 8);  
          printf("rand = %d",r);  
      }  
       
      ibug = ibug + imove[r];  
      jbug = jbug + jmove[r];  
      count[ibug][jbug] = count[ibug][jbug] + 1;    
      //printf("%d",count[ibug][jbug]);  


Devrait être dans une grande boucle que tu iteres 50 000 fois, non?
Parce que la, avec ton code, ta bete fait un deplacement et c'est fini.
 
D'autre part

Citation :

//Test sur toutes les valeurs du tableau count si 3 passages

 
Tu teste si elle est passée exactement trois fois sur chaque case. A priori, ca devrait être au moins trois fois, non?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-12-2007 à 07:03:30    

ah oui ! merci beaucoup je fais les modifications de suite !
il me reste plus qu'un problème je pense, c'est qui si je met dans la boucle je ne sortirais de celle ci que lorsque les 50 000 auront été atteind hors il faut que j'en sorte aussi si il y a au moins 3 passages dans chacune des cases. voici les modifications :
 
je pense que je dois inclure mon test des 3 passages dans la boucle mais je ne vois pas trop comment faire pour qu'elle pousse la boucle a se terminer...
Merci beaucoup pour l'aide !


Message édité par yokooo le 07-12-2007 à 17:59:47
Reply

Marsh Posté le 07-12-2007 à 11:51:49    

Tu veux dire que tu peux t'arreter des que la bete est passee 3 fois partout?
C'est facile: avant ta grande boucle, tu met une variable a 0 qui va compter le nb de case ou la bete est passée 3 fois
apres avoir fait count[ibug][jbug] = count[ibug][jbug] + 1;
si maintenant count[ibug][jbug] == 3, tu incremente ta variable.
quand ta variable vaut m*n la bebete est passe 3 fois partout.
Tu peux donc faire un test d'arret de ta boucle avec 50000 tours ou bien ta variable == m*n
Et tu peux donc virer ton test sur toutes les valeurs du tableau count si 3 passages qui suit la boucle.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-12-2007 à 12:15:47    

voila les modification apportées... ça ne marche pas... je ne vois pas pourquoi !
celà doit etre due à une petite erreur...
 


Message édité par yokooo le 07-12-2007 à 18:00:00
Reply

Marsh Posté le 07-12-2007 à 15:27:17    

Citation :

while(ok < (n*m) || k < 50000)


Ca ne me semble pas d'une efficacité parfaite ce test... :whistle:  
Tu ne t'arreteras jamais avant les 50000 tours.
De plus k ne me semble pas être initialisé dans ton code.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 07-12-2007 à 17:58:31    

C'est bon j'ai fais les modifs et tout fonctionne !!!! :-)
Merci beaucoup pour tous ces conseils !!!
 
A locker ! :-)
 
Geoffrey

Reply

Marsh Posté le 07-12-2007 à 21:52:38    

Bon eh bien tant mieux.
Je me suis amusé a coder cela avec une variante sur le trajet aléatoire de la bestiole afin de ne pas générer de mouvements impossibles qui sont rejetés par la suite.
Ce qui est marrant, c'est que si tu fais aller la bestiole de maniere totallement aléatoire (ie la position d'une case a la suivante au hasard) c'est bien plus rapide que s'il ne change de trajectoire qu'en rencontrant un bord (ce que fait ta solution, au vu de ton code, a priori)
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <conio.h>
  5. #include <time.h>
  6. #define MAX_ITERATIONS 50000
  7. #define MIN_BOARD_LENGTH 2
  8. #define MAX_BOARD_LENGTH 40
  9. #define MIN_BOARD_WIDTH 2
  10. #define MAX_BOARD_WIDTH 20
  11. typedef struct{
  12.     int length;
  13.     int width;
  14.     int **squares;
  15.   }boardT;
  16. typedef struct{
  17.     int xpos;
  18.     int ypos;
  19. }bugT;
  20. void bug_initial_pos(bugT *bug, boardT *board)
  21. {
  22.    // Ici va etre géré les conditions pour n=m=15, n=m=1 et si n et m ont une valeur quelconque
  23.       if ( board->length == 15 && board->width == 15)
  24. {
  25.   bug->xpos = 10;
  26.   bug->ypos = 10;
  27. }
  28.       else if ( board->length == 39 && board->width == 19)
  29. {
  30.   bug->xpos = 1;
  31.   bug->ypos = 1;
  32. }
  33.       else
  34. {
  35.   bug->xpos = board->length/2;
  36.   bug->ypos = board->width/2;
  37. }
  38.       board->squares[bug->xpos][bug->ypos]++;
  39.   return;
  40. }
  41. /* Cette fonction deplace la bete sur une nouvelle position
  42.    elle retourne 1 si c'est le 3e passage sur vette position,  
  43.    et 0 sinon */
  44. int bug_new_pos(bugT *bug, boardT *board)
  45. {
  46.   static int moves[9][8][2] = {
  47.   {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}},  // Unconstrained position, 8 moves  
  48.   {{1,0},{1,1},{0,1},{-1,1},{-1,0},{0,0},{0,0},{0,0}},      // Non-Corner (X,0), 5 moves
  49.   {{-1,0},{-1,-1},{0,-1},{1,-1},{1,0},{0,0},{0,0},{0,0}},   // Non-Corner (X,W-1), 5 moves
  50.   {{0,-1},{1,-1},{1,0},{1,1},{0,1},{0,0},{0,0},{0,0}},      // Non-Corner (0,X), 5 moves
  51.   {{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{0,0},{0,0},{0,0}},   // Non-Corner (L-1,X), 5 moves
  52.   {{1,0},{1,1},{0,1},{0,0},{0,0},{0,0},{0,0},{0,0}},        // Corner (0,0), 3 moves  
  53.   {{0,-1},{1,-1},{1,0},{0,0},{0,0},{0,0},{0,0},{0,0}},      // Corner (0,W-1), 3 moves
  54.   {{-1,0},{-1,-1},{0,-1},{0,0},{0,0},{0,0},{0,0},{0,0}},    // Corner (L-1,W-1), 3 moves
  55.   {{0,1},{-1,1},{-1,0},{0,0},{0,0},{0,0},{0,0},{0,0}}       // Corner (L-1,0), 3 moves
  56. };
  57.   static int index, move;  // static pour être réutilises pour la trajectoire linéaire
  58.   static int first = 1;
  59.   int i = bug->xpos;
  60.   int j = bug->ypos;
  61.   int l = board->length -1;
  62.   int w = board->width -1;
  63.   /* A partir de la position courante, determine quelle mouvements sont possibles
  64.      c'est a dire quelle ligne du tableau moves va être concernée */
  65.   if (i == 0)
  66.     if (j == 0) index = 5;
  67.     else if (j == w) index = 6;
  68.     else index = 3;
  69.   else if (i == l)
  70.     if (j == 0) index = 8;
  71.     else if (j == w) index = 7;
  72.     else index = 4;
  73.   else if (j == 0) index = 1;
  74.   else if (j == w) index = 2;
  75.   else index = 0;
  76.   switch(index) {
  77.   case 0:  if (first) /* si on vire ce test, le deplacement est aléatoire a chaque étape  
  78.   sinon, il va en ligne droite tant qu'un bord n'est pas atteint,
  79.          et il met donc plus de temps a couvrir trois fois toutes mles cases */
  80.       {
  81. move = (rand() % 8);
  82. first = 0;
  83.       }
  84.     break;
  85.   case 1:
  86.   case 2:
  87.   case 3:
  88.   case 4: move = (rand() % 5);
  89.     break;
  90.   case 5:
  91.   case 6:
  92.   case 7:
  93.   case 8: move = (rand() % 3);
  94.     break;
  95.   default:; /* WTF! */
  96.   }
  97.  
  98.   bug->xpos += moves[index][move][0];
  99.   bug->ypos += moves[index][move][1];
  100.   board->squares[bug->xpos][bug->ypos]++;
  101.   if (board->squares[bug->xpos][bug->ypos] == 3)
  102.     return 1;
  103.   else
  104.     return 0;
  105. }
  106. void print_board(boardT *board)
  107. {
  108.   int i,j;
  109.   for (i=0;i<board->length;i++)
  110.     {
  111.       for (j=0;j<board->width;j++)
  112. {
  113.   printf("| %.5d ", board->squares[i][j]);
  114. }
  115.       printf("|\n" );
  116.     }
  117. }
  118. int main(int argc, int **argv)
  119. {
  120.   boardT board;
  121.   bugT bug;
  122.   int iteration_count;
  123.   int remaining_squares;
  124.   int i;
  125.       // Nombre de lignes et colonnes rentré par l'utilisateur
  126.       printf("Rentrez les valeurs de n (entre 2 et 40) puis m (entre 2 et 20)\n" );
  127.       scanf("%d%d", &board.length, &board.width);
  128.       while( board.length < MIN_BOARD_LENGTH
  129.      || board.length > MAX_BOARD_LENGTH
  130.      || board.width < MIN_BOARD_WIDTH
  131.      || board.width > MAX_BOARD_WIDTH  )
  132.       {
  133.             printf("Erreur de saisie !!!\nRentrez une nouvelle valeur pour n puis pour n\n" );     
  134.             scanf("%d%d", &board.length, &board.width);
  135.       }
  136.       //Allocation du tableau juste sur une dimension en fonction de la valeur de n  
  137.       board.squares  = malloc(board.length*sizeof(int));
  138.       for (i=0;i<board.length;i++)
  139. board.squares[i] = calloc(board.width, sizeof(int));
  140.       remaining_squares = board.length * board.width;
  141.       iteration_count = 0;
  142.       bug_initial_pos(&bug, &board); 
  143.       srand(time(NULL)); /* inutile de réinitialiser 50000 fois */
  144.       do
  145. if (bug_new_pos(&bug, &board))
  146.   remaining_squares--;
  147. iteration_count++; 
  148.       } while( remaining_squares && iteration_count < MAX_ITERATIONS);
  149.      
  150.       if (!remaining_squares)
  151.       {
  152.          printf("La blatte est passee trois fois sur chacune des cases\n" );
  153.  printf("iteration %d\n", iteration_count);
  154.       }
  155.       else printf("La blate n'a pas fait tous les carreaux trois fois\n" );
  156.       print_board(&board);
  157.       getch(); // pour ne pas quitter windows trop vite
  158.      
  159.       /* inutile car l'OS peut le faire, mais pourquoi ne pas le faire soi meme
  160.  histoire d'acquérir de bonnes habitudes */
  161.       for (i=0;i<board.length;i++)
  162. free (board.squares[i]);
  163.       free(board.squares);
  164.       return 0;
  165. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 08-12-2007 à 00:18:18    

matafan a écrit :

Je suis pas sûr de bien avoir compris comment tu procèdes Joel. T c'est le tableau de H pointeurs, c'est ça ? Dans ce cas pour accéder à T[i][j] tu va d'abord lire l'adresse en T[i] (l'adresse de ta colonne), puis ensuite la valeur à cette adresse + j ? Comment ça peux être plus rapide qu'aller simplement lire la valeur à l'adresse B + H*i+j où B est ton bloc de H*W éléments (bloc contigu dans les deux cas) ? Surtout que la plupart des proc on un instruction qui fait mul et add en un coup ?

 

En gros :

 
Code :
  1. template<class T>
  2. T** alloc_array( int h, int w )
  3. {
  4.   typedef T*           ptr_type;
  5.   typedef ptr_type* return_type;
  6.   return_type m = new ptr_type[h];
  7.   m[0] = new T[h*w];
  8.   for(int i=1;i<h;i++) m[i] = m[i-1]+w;
  9.   return m;
  10. }
  11. template<class T>
  12. void release_array(T** m)
  13. {
  14.   delete[] m[0];
  15.   delete[] m;
  16. }
  17. // Exemple d'accés :
  18. m[5][4] = 3;
 

L'acces T[i][j] avec cette methode ne necessite qu'une addition, et non pas une addition + une multiplication. Fait le test toi-même tu verras. J'etait persuadé du contraire jusqu'à ce que je fasse l'essai, que je bench et que j'etudie l'assembleur généré dasn ce cas et le cas t[i+j*H] sous intel et PPC, gcc, Visual ou icc.
En fait, t[i+j*] ca n'utilise pas de madd (surtout parce que n'a n'existe pas en scalaire) mais des blagues avec des MOV et des LEA ... et LEA <<< ADD
Pour ref, c'est la méthode préconisée par Numerical Recipes.

Message cité 2 fois
Message édité par Joel F le 06-01-2011 à 08:32:16
Reply

Marsh Posté le 08-12-2007 à 21:53:55    

Joel F a écrit :

tu veut creer un tableau HxW :
tu alloue un bloc de HxW elements
tu allour un tablea de H pointeurs
tu remplis ce tableau avec les offsets de colonnes.
 
Moralité :
tu accédes en T[i][j]
tu n'as qu'un bloc contigue (bon pr le cache)
 
Et ce qui me fait dire ça : ma thése sur le sujet + 2 ans de travaux en Traitement d'images haute performances :o
 
Le truc A NE PAS FAIRE : allouer un tableau de pointeur et allouer W pointeur differents discontinues

Amen
Mais boost ?

Reply

Marsh Posté le 08-12-2007 à 21:57:44    

Joel F a écrit :


 
En gros :
 

Code :
  1. template<class T>
  2. T** alloc_array( int h, int w )
  3. {
  4.   T** m = new (T*)[h];
  5.   m[0] = new T[h*w];
  6.   for(int i=1;i<h;i++) m[i] = m[i-1]+w;
  7.   return m;
  8. }
  9. template<class T>
  10. void release_array(T** m)
  11. {
  12.   delete m[0];
  13.   delete m;
  14. }
  15. // Exemple d'accés :
  16. m[5][4] = 3;


 
L'acces T[i][j] avec cette methode ne necessite qu'une addition, et non pas une addition + une multiplication. Fait le test toi-même tu verras. J'etait persuadé du contraire jusqu'à ce que je fasse l'essai, que je bench et que j'etudie l'assembleur généré dasn ce cas et le cas t[i+j*H] sous intel et PPC, gcc, Visual ou icc.  
En fait, t[i+j*] ca n'utilise pas de madd (surtout parce que n'a n'existe pas en scalaire) mais des blagues avec des MOV et des LEA ... et LEA <<< ADD  
Pour ref, c'est la méthode préconisée par Numerical Recipes.


Toi t'as jamais vu des vrais gars de la fac faire des i x 3 en allouant bien chaque float[3] à coup de malloc. Un régal. "bah pourquoi tu fais de la merde comme ça ? - bah je fais pareil en java"

Reply

Marsh Posté le 08-12-2007 à 22:01:35    

(au fait ton truc est pas bon, faut passer par un typedef)

Reply

Marsh Posté le 08-12-2007 à 22:36:16    

oui pour le pointeur T* , j'ai tapé de tête, je corrige.

Reply

Marsh Posté le 08-12-2007 à 22:37:53    

Taz a écrit :

Amen
Mais boost ?


 
sta dire ?

Reply

Marsh Posté le 09-12-2007 à 00:01:47    

multi_array. J'ai jamais regardé l'alloc, mais le code généré à l'accès aux éléments est le bon (je l'avais prouvé dans un topic là dessus).

Reply

Marsh Posté le 09-12-2007 à 14:11:29    

Taz a écrit :

multi_array. J'ai jamais regardé l'alloc, mais le code généré à l'accès aux éléments est le bon (je l'avais prouvé dans un topic là dessus).


lien? stp  :jap:


---------------
--- WinSplit Revolution ---
Reply

Marsh Posté le 09-12-2007 à 16:29:44    

j'aurais aimé savoir si a partir du codage ci dessous il était possible de faire un affichage graphique indiquant toutes les cases et le nombre de passage à l'intérieur ? merci

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <conio.h>
  5. #include <time.h>
  6. int n,m,i,j,k=0,l,na,ma,ibug,jbug;
  7. int **count;
  8. int r,ok;
  9. int imove[8] = {-1,0,1,1,1,0,-1,-1};
  10. int jmove[8] = {1,1,1,0,-1,-1,-1,0};
  11. main()
  12. {
  13.       // Nombre de lignes et colonnes rentré par l'utilisateur
  14.       printf("Rentrez les valeurs de n (entre 2 et 40) puis m (entre 2 et 20)\n" );
  15.       scanf("%d%d",&n,&m);
  16.      
  17.       //Si les valeurs ne sont pas comprises dans l'intervalle l'utilisateur les resaisies jusqu'à ce qu'elles soient correctes
  18.       while(n>40 || n<2 || m>20 || m<2)
  19.       {
  20.             printf("Erreur de saisie !!!\nRentrez une nouvelle valeur pour n puis pour n\n" );     
  21.             scanf("%d%d",&n,&m);
  22.       }
  23.      
  24.       //Réallocation du tableau juste sur une dimension en fonction de la valeur de n       
  25.       count = malloc(n*sizeof(int));
  26.       for (i=0;i<n;i++)
  27.       {
  28.             //Réallocation du tableau sur la 2ème dimension en fonction de la valeur de m  
  29.             count[i] = malloc(m*sizeof(int));
  30.             for (j=0;j<m;j++)
  31.             {
  32.                  //Mise à 0 de tableau affichant le nombre de passages
  33.                  count[i][j]=0;
  34.             }
  35.       }
  36.      
  37.       // Ici va etre géré les conditions pour n=m=15, n=m=1 et si n et m ont une valeur quelconque
  38.       if (n == 15 && m == 15)
  39.       {
  40.             ibug = 10;
  41.             jbug = 10;
  42.       }
  43.       else
  44.       {
  45.             if (n == 39 && m == 19)
  46.             {
  47.                   ibug = 1;
  48.                   jbug = 1;
  49.             }
  50.             else
  51.             {
  52.                   ibug = n/2;
  53.                   jbug = m/2;
  54.             }
  55.       }
  56.       //printf("bug = %d",ibug);
  57.       ok = 0; 
  58.       r=0;
  59.      
  60.      
  61.       while(ok < (n*m) && k < 50000)
  62.       {
  63.          do        {
  64.              srand(time(NULL));
  65.              r = (rand() % 8);
  66.              //printf("rand = %d",r);
  67.          }while((imove[r]+ibug<0) || (jmove[r]+jbug<0) || (imove[r]+ibug>=n) || (jmove[r]+jbug>=m));
  68.      
  69.          ibug = ibug + imove[r];
  70.          jbug = jbug + jmove[r];
  71.          count[ibug][jbug] = count[ibug][jbug] + 1; 
  72.          //printf("%d",count[ibug][jbug]);
  73.          if (count[ibug][jbug] != 0)
  74.          {
  75.             ok = ok + 1;
  76.          }
  77.          k++;
  78.        
  79.       }
  80.            
  81.       if (ok == (n*m))
  82.       {
  83.          printf("La blatte est passee trois fois sur chacune des cases" );
  84.       }
  85.       else printf("La blate n'a pas fait tous les carreaux trois fois" );
  86.      
  87.       getch();
  88. }


Message édité par yokooo le 09-12-2007 à 16:32:48
Reply

Marsh Posté le 09-12-2007 à 16:51:27    

Adaptes celle de ce que j'ai donné en exemple, c'est pas bien dur.
 

Code :
  1. void print_board(boardT *board)
  2. {
  3.   int i,j;
  4.   for (i=0;i<board->length;i++)
  5.     {
  6.       for (j=0;j<board->width;j++)
  7. {
  8.   printf("| %.5d ", board->squares[i][j]);
  9. }
  10.       printf("|\n" );
  11.     }
  12. }


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-12-2007 à 16:58:55    

voila ce que j'ai fait ... mais ça ne marche pas... peut tu m'expliquer pourquoi ?

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <conio.h>
  5. #include <time.h>
  6. typedef struct{
  7.     int length;
  8.     int width;
  9.     int **squares;
  10.   }boardT;
  11. int n,m,i,j,k=0,l,na,ma,ibug,jbug;
  12. int **count;
  13. int r,ok;
  14. int imove[8] = {-1,0,1,1,1,0,-1,-1};
  15. int jmove[8] = {1,1,1,0,-1,-1,-1,0};
  16. void print_board(boardT *board)
  17. {
  18.   int i,j;
  19.   for (i=0;i<board->length;i++)
  20.     {
  21.       for (j=0;j<board->width;j++)
  22. {
  23.   printf("| %.5d ", board->squares[i][j]);
  24. }
  25.       printf("|\n" );
  26.     }
  27. }
  28. main()
  29. {
  30.       boardT board;
  31.       // Nombre de lignes et colonnes rentré par l'utilisateur
  32.       printf("Rentrez les valeurs de n (entre 2 et 40) puis m (entre 2 et 20)\n" );
  33.       scanf("%d%d",&n,&m);
  34.      
  35.       //Si les valeurs ne sont pas comprises dans l'intervalle l'utilisateur les resaisies jusqu'à ce qu'elles soient correctes
  36.       while(n>40 || n<2 || m>20 || m<2)
  37.       {
  38.             printf("Erreur de saisie !!!\nRentrez une nouvelle valeur pour n puis pour n\n" );     
  39.             scanf("%d%d",&n,&m);
  40.       }
  41.      
  42.       //Réallocation du tableau juste sur une dimension en fonction de la valeur de n       
  43.       count = malloc(n*sizeof(int));
  44.       for (i=0;i<n;i++)
  45.       {
  46.             //Réallocation du tableau sur la 2ème dimension en fonction de la valeur de m  
  47.             count[i] = malloc(m*sizeof(int));
  48.             for (j=0;j<m;j++)
  49.             {
  50.                  //Mise à 0 de tableau affichant le nombre de passages
  51.                  count[i][j]=0;
  52.             }
  53.       }
  54.      
  55.       // Ici va etre géré les conditions pour n=m=15, n=m=1 et si n et m ont une valeur quelconque
  56.       if (n == 15 && m == 15)
  57.       {
  58.             ibug = 10;
  59.             jbug = 10;
  60.       }
  61.       else
  62.       {
  63.             if (n == 39 && m == 19)
  64.             {
  65.                   ibug = 1;
  66.                   jbug = 1;
  67.             }
  68.             else
  69.             {
  70.                   ibug = n/2;
  71.                   jbug = m/2;
  72.             }
  73.       }
  74.       //printf("bug = %d",ibug);
  75.       ok = 0; 
  76.       r=0;
  77.      
  78.      
  79.       while(ok < (n*m) && k < 50000)
  80.       {
  81.          do        {
  82.              srand(time(NULL));
  83.              r = (rand() % 8);
  84.              //printf("rand = %d",r);
  85.          }while((imove[r]+ibug<0) || (jmove[r]+jbug<0) || (imove[r]+ibug>=n) || (jmove[r]+jbug>=m));
  86.      
  87.          ibug = ibug + imove[r];
  88.          jbug = jbug + jmove[r];
  89.          count[ibug][jbug] = count[ibug][jbug] + 1; 
  90.          //printf("%d",count[ibug][jbug]);
  91.          if (count[ibug][jbug] != 0)
  92.          {
  93.             ok = ok + 1;
  94.          }
  95.          k++;
  96.        
  97.       }
  98.              
  99.       if (ok == (n*m))
  100.       {
  101.          printf("La blatte est passee trois fois sur chacune des cases" );
  102.       }
  103.       else
  104.       {
  105.       printf("La blate n'a pas fait tous les carreaux trois fois" );
  106.       }
  107.       print_board(&board);
  108.      
  109.       getch();
  110. }


 
aussi que qignifit cette ligne ?

Citation :

printf("| %.5d ", board->squares[i][j]);


 
merci infiniment !

Message cité 1 fois
Message édité par yokooo le 09-12-2007 à 22:50:33
Reply

Marsh Posté le 09-12-2007 à 18:37:51    

Taz a écrit :

multi_array. J'ai jamais regardé l'alloc, mais le code généré à l'accès aux éléments est le bon (je l'avais prouvé dans un topic là dessus).


 
ouais je sais. J'ai besoin de plus que ça pour gérer mes Expr. templates et mon code de parallelisation automatique ;)

Reply

Marsh Posté le 09-12-2007 à 21:18:11    

yokooo a écrit :


aussi que qignifit cette ligne ?

Citation :

printf("| %.5d ", board->squares[i][j]);


 
merci infiniment !

printf, tu connais je suppose.  
j'imprimes un | un espace, le nombre de fois qu'on est passe dans la case [i][j] du tableau, puis un autre espace.  
Ce qui fait qu'en faisant ca pour tous les element d'une ligne, ca donne quelque chose de la forme:
| 00111 | 00022 | 03321 | 00001
il faut donc aussi imprimer un | avant de passer a la ligne suivante.
le %.5d sert a avoir des cases de taille constante, tous les nombres etant imprimés avec 5 chiffres.
Le 5 est choisi parce que au maximum, le valeur dans une cas eest 50000, ce qui tient sur 5 chiffres.
 
Si au lieu de copier coller betement mon code, tu avais essayé de comprendre ce qu'il fait, tu aurais vu qur mon int **squares correspond a ton int **count, et tu aurais adapté le code d'impression. Parce que la, il n'y a aucune chance que ca marche, avec le copier coller de la fonction que tu as fait.
Il ne faudrait peut etre pas esperer que je recode la fonction a ta place, ce n'est pas le principe de ce forum.
 
A+,


Message édité par gilou le 09-12-2007 à 21:24:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-12-2007 à 21:44:02    

Taz a écrit :

multi_array. J'ai jamais regardé l'alloc, mais le code généré à l'accès aux éléments est le bon (je l'avais prouvé dans un topic là dessus).


 
T'es sur ?? Quand je vois ça :  
 

Code :
  1. TPtr newbase = base + idx * strides[0];


 
J'en doute :s

Reply

Marsh Posté le 09-12-2007 à 22:43:32    

ah oui effectivement j'avais oublié de changer le squares... :sweat:  
bon j'ai tout repris en modifiant ce qu'il fallait mais il me reste une erreur de syntaxe...

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <conio.h>
  5. #include <time.h>
  6. int n,m,i,j,k=0,l,na,ma,ibug,jbug;
  7. int **count;
  8. int r,ok;
  9. int imove[8] = {-1,0,1,1,1,0,-1,-1};
  10. int jmove[8] = {1,1,1,0,-1,-1,-1,0};
  11. void afficher(int count[][], int n, int m)
  12. {
  13.   int i,j;
  14.   for (i=0;i<n;i++)
  15.     {
  16.       for (j=0;j<m;j++)
  17. {
  18.   printf("| %.5d ", count[i][j]);
  19. }
  20.       printf("|\n" );
  21.     }
  22. }
  23. main()
  24. {
  25.       // Nombre de lignes et colonnes rentré par l'utilisateur
  26.       printf("Rentrez les valeurs de n (entre 2 et 40) puis m (entre 2 et 20)\n" );
  27.       scanf("%d%d",&n,&m);
  28.      
  29.       //Si les valeurs ne sont pas comprises dans l'intervalle l'utilisateur les resaisies jusqu'à ce qu'elles soient correctes
  30.       while(n>40 || n<2 || m>20 || m<2)
  31.       {
  32.             printf("Erreur de saisie !!!\nRentrez une nouvelle valeur pour n puis pour n\n" );     
  33.             scanf("%d%d",&n,&m);
  34.       }
  35.      
  36.       //Réallocation du tableau juste sur une dimension en fonction de la valeur de n       
  37.       count = malloc(n*sizeof(int));
  38.       for (i=0;i<n;i++)
  39.       {
  40.             //Réallocation du tableau sur la 2ème dimension en fonction de la valeur de m  
  41.             count[i] = malloc(m*sizeof(int));
  42.             for (j=0;j<m;j++)
  43.             {
  44.                  //Mise à 0 de tableau affichant le nombre de passages
  45.                  count[i][j]=0;
  46.             }
  47.       }
  48.      
  49.       // Ici va etre géré les conditions pour n=m=15, n=m=1 et si n et m ont une valeur quelconque
  50.       if (n == 15 && m == 15)
  51.       {
  52.             ibug = 10;
  53.             jbug = 10;
  54.       }
  55.       else
  56.       {
  57.             if (n == 39 && m == 19)
  58.             {
  59.                   ibug = 1;
  60.                   jbug = 1;
  61.             }
  62.             else
  63.             {
  64.                   ibug = n/2;
  65.                   jbug = m/2;
  66.             }
  67.       }
  68.       //printf("bug = %d",ibug);
  69.       ok = 0; 
  70.       r=0;
  71.      
  72.      
  73.       while(ok < (n*m) && k < 50000)
  74.       {
  75.          do        {
  76.              srand(time(NULL));
  77.              r = (rand() % 8);
  78.              //printf("rand = %d",r);
  79.          }while((imove[r]+ibug<0) || (jmove[r]+jbug<0) || (imove[r]+ibug>=n) || (jmove[r]+jbug>=m));
  80.      
  81.          ibug = ibug + imove[r];
  82.          jbug = jbug + jmove[r];
  83.          count[ibug][jbug] = count[ibug][jbug] + 1; 
  84.          //printf("%d",count[ibug][jbug]);
  85.          if (count[ibug][jbug] != 0)
  86.          {
  87.             ok = ok + 1;
  88.          }
  89.          k++;
  90.        
  91.       }
  92.            
  93.       if (ok == (n*m))
  94.       {
  95.          printf("La blatte est passee sur chacune des cases" );
  96.       }
  97.       else printf("La blate n'a pas fait tous les carreaux" );
  98.      
  99.       afficher(&count,n,m);
  100.      
  101.       getch();
  102. }


et les erreurs sont :

Citation :

20 : invalid use of array with unspecified bounds  
103 : [Warning] passing arg 1 of `afficher' from incompatible pointer type  

Message cité 1 fois
Message édité par yokooo le 09-12-2007 à 22:44:39
Reply

Marsh Posté le 10-12-2007 à 09:39:51    

Reply

Marsh Posté le 10-12-2007 à 11:10:27    

yokooo a écrit :

ah oui effectivement j'avais oublié de changer le squares... :sweat:  
bon j'ai tout repris en modifiant ce qu'il fallait mais il me reste une erreur de syntaxe...
 
et les erreurs sont :

Citation :

20 : invalid use of array with unspecified bounds  
103 : [Warning] passing arg 1 of `afficher' from incompatible pointer type  


Tu fais un passage de parametre par addresse:
afficher(&count,n,m);
 
Il faut donc que ce soit le cas avec ta fonction:
void afficher(int (*count)[][], int n, int m)
ou  
void afficher(int ***count, int n, int m)
si ton compilo n'aime pas la précédente déclaration.
et dans cette fonction, tu modifies les appels en appelant le tableau pointé
printf("| %.5d ", (*count)[i][j]);
 
A+,


Message édité par gilou le 10-12-2007 à 11:11:02

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 10-12-2007 à 13:04:32    

ok c'est bon le programme se compile, mais...
il ne fonctionne pas...
il me dit que la blatte est passée sur tous les carreaux mais lors de l'affichage des cases il y en a certaines qui indiquent zéro...

Reply

Marsh Posté le 10-12-2007 à 21:26:40    

yokooo a écrit :

ok c'est bon le programme se compile, mais...
il ne fonctionne pas...
il me dit que la blatte est passée sur tous les carreaux mais lors de l'affichage des cases il y en a certaines qui indiquent zéro...

Normal, vu qu'en ecrivant ton code, tu fais n'importe quoi:

Citation :

if (count[ibug][jbug] != 0)
         {
            ok = ok + 1;
         }

C'est quoi la condition pour pouvoir incrementer ok?? :pfff:  
A priori, avec ce code, tu dois jamais depasser les 2*m*n iterations.
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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