Fonction de C++ pas tout à fait au point, si quelqu'un à une idée

Fonction de C++ pas tout à fait au point, si quelqu'un à une idée - Programmation

Marsh Posté le 15-04-2001 à 20:39:56    

Salut, je veux faire une fonction qui parcours une matrice 20X20 qui ne contient que des 1 ou des 0. Cette fonction doit pouvoir identifier toutes les régions ou les 1 sont voisins soit horizontalement,verticalement et non pas de façon diagonale, et doit pouvoir donner à ces régions la valeur du compte.  C'est-à-dire, le premier amoncellement de 1 demeure comme tel, le deuxième amoncellement devient des deux, le troisième devient des trois et ainsi de suite.
 
J'ai écrit cette fonction, mais elle ne fonctionne pas parfaitement dans les coins de la matrice et elle laisse toujours les premiers 1 d'un amoncellement qui sont sur une même ligne à 1 et non pas à la valeur du compte.
 
int cpt=0;
 
for (i=0; i<20; i++)
for (j=0; j<20; j++)
 
{
if (tab[i][j] && tab[i+1][j]) {tab[i+1][j]=tab[i][j]=cpt++;}
else if (tab[i][j] && tab[i-1][j]) {tab[i][j]=tab[i-1][j];}
else if (tab[i][j] && tab[i][j-1]) {tab[i][j]=tab[i][j-1];}
else if (tab[i][j] && tab[i][j+1]) {tab[i][j]=tab[i][j+1];}
}
 
Si quelqu'un sait commet faire pour corriger la situation, ce serait fort apprécier.
 
merci à tous[quote]

Reply

Marsh Posté le 15-04-2001 à 20:39:56   

Reply

Marsh Posté le 15-04-2001 à 20:59:27    

C'est assez imprécis comme comportement.
Que devrait donner la matrice suivante (en 4x4) ?
1 0 0 1
1 1 1 0
0 0 1 1
1 1 0 1

Reply

Marsh Posté le 15-04-2001 à 21:04:57    

Ça devrait donner ceci
1 0 0 2
1 1 1 0
0 0 1 1
3 3 0 1
 
autre exemple:
0 0 1 0
0 1 1 0
1 0 0 0
1 1 0 1
devient:
0 0 1 0
0 1 1 0
2 0 0 0
2 2 0 3
 
Voilà, j'espère que c'est moins confus comme ça.

Reply

Marsh Posté le 15-04-2001 à 21:42:14    

Je pense qu'il n'y a pas de solution en une seule passe (un seul parcours du tableau).
En effet on doit toujours pouvoir trouver des configurations pour lesquelles 2 parties qui semblaient déconnectées en début d'analyse sont en fait reliées.

Reply

Marsh Posté le 16-04-2001 à 05:50:38    

Est-ce que quelqu'un sait comment faire pour le faire en une seule passe?

Reply

Marsh Posté le 16-04-2001 à 21:08:47    

J'ai modifié un peu la chose, et maintenant je m'en vais comme suit:
for (i=0; i<20; i++)
for (j=0; j<20; j++)
 
 
//Coin en haut à gauche
if ((i==0) && (j==0)) {
 if (tab[i][j] && tab[i+1][j] && tab[i][j+1]) {tab[i+1][j]=tab[i][j+1]=tab[i][j]=cpt++;}
 else if (tab[i][j] && tab[i+1][j]) {tab[i+1][j]=tab[i][j]=cpt++;}
 else if (tab[i][j] && tab[i][j+1]) {tab[i][j+1]=tab[i][j]=cpt++;}
 else if ((tab[i][j]==1)&&(tab[i+1][j]==0)&&(tab [i][j+1]==0)) {tab[i][j]=cpt++;};
}
//Ligne du haut
else if ((i==0) && (j!=0) && (j!=19)) {
 if (tab[i][j] && tab[i][j-1] && tab[i][j+1] && tab[i+1][j]) {tab[i][j]=tab[i+1][j]=tab[i][j+1]=tab[i][j-1];}
 else if (tab[i][j] && tab[i+1][j] && tab[i][j-1]) {tab[i+1][j]=tab[i][j]=tab[i][j-1];}
 else if (tab[i][j] && tab[i+1][j] && tab[i][j+1]) {tab[i][j+1]=tab[i+1][j]=tab[i][j]=cpt++;}
 else if (tab[i][j] && tab[i][j+1] && tab[i][j-1]) {tab[i][j+1]=tab[i][j]=tab[i][j-1];}
 else if (tab[i][j] && tab[i][j+1]) {tab[i][j+1]=tab[i][j]=cpt++;}
 else if (tab[i][j] && tab[i][j-1]) {tab[i][j]=tab[i][j-1];}
 else if (tab[i][j] && tab[i+1][j]) {tab[i+1][j]=tab[i][j]=cpt++;}
 else if ((tab[i][j]==1)&&(tab[i+1][j]==0)&&(tab[i][j-1]==0)&&(tab[i][j+1]==0)) {tab[i][j]=cpt++;};
}
//Coin en haut à droite
else if ((i==0) && (j==19)) {
 if (tab[i][j] && tab[i][j-1] && tab[i+1][j]) {tab[i][j]=tab[i+1][j]=tab[i][j-1];}
 else if (tab[i][j] && tab[i][j-1]) {tab[i][j]=tab[i][j-1];}
 else if (tab[i][j] && tab[i+1][j]) {tab[i+1][j]=tab[i][j]=cpt++;}
 else if ((tab[i][j]==1) && (tab[i+1][j]==0) && (tab[i][j-1]==0)) {tab[i][j]=cpt++;};
}
{.......}
 
De cette façon ça fonctionne, mais il n'y aurait pas un moyen plus simple et plus court?

Reply

Marsh Posté le 16-04-2001 à 21:14:28    

Ca marche aussi avec une config du genre ?:
1 0 1 0 1
1 0 1 0 1
1 0 0 0 1
1 1 1 1 1

Reply

Marsh Posté le 16-04-2001 à 21:18:10    

oui

Reply

Marsh Posté le 16-04-2001 à 23:00:22    

Do!!  Je crois bien avoir parlé trop vite.  Effectivement, il y a un petit pépin.  
Quelqu'un a une idée pour le régler?

Reply

Marsh Posté le 17-04-2001 à 00:24:28    

Verdoux, t'aurais pas une idée?
Y a t-il moyen de circuler dans la matrice dans le sens inverse?

Reply

Marsh Posté le 17-04-2001 à 00:24:28   

Reply

Marsh Posté le 17-04-2001 à 01:35:22    

Est-ce qu'il y aurait moyen de faire une deuxième fonction qui retraite l'image pour corriger les problèmes survenus lorsqu'il y a des U de former dans l'image???

Reply

Marsh Posté le 17-04-2001 à 01:49:44    

Une solution serait de parcourir la matrice et à chaque fois que tu tombes sur un 1 tu parcours tout "l'ilôt" auquel il appartient (récursivement, de proche en proche). Pour éviter de parcourir plusieurs fois les mêmes points il faut associer une autre matrice 20x20 initialisée à 0 et que tu remplis par des 1 lorsque tu a parcouru un point.

Reply

Marsh Posté le 17-04-2001 à 02:30:04    

Bonjour à toutes et à tous,
 
Ce problème peu facilement se résoudre grâce à la récursivité.
Voici un petit programme qui va le faire.
 
Salutations
-------------------------------------------------
#define NBX 20
#define NBY 20
 
int Tab[NBX][NBY];
 
// Teste la case de coordonnées x,y et la marque avec la valeur de cpt
// si elle appartient au groupe adjacent.
void Recherche(int x, int y, int cpt)
{
   if (x<0 || x>=NBX || y<0 || y>=NBY)
      return; // si les coordonnées de la case à tester ne sont pas valides
   else if (Tab[x][y]!=1)
      return; // si la case a déjà été marquée ou s'il y a un 0
   else
   {
      Tab[x][y]=cpt; // on marque la case
      Recherche(x-1,y,cpt); // on teste les 4 directions récursivement
      Recherche(x+1,y,cpt);
      Recherche(x,y-1,cpt);
      Recherche(x,y+1,cpt);
   }
}
 
main()
{
   int i,j,cpt;
 
   // initailisation de Tab uniquement avec des 0 et 1
 
   cpt=2; // on initialise le compteur à 2 car le 1 est déjà utilisé
 
   for (j=0;j<NBY;j++)
      for (i=0;i<NBX;i++)
         if (Tab[i][j]==1)
            Recherche(i,j,cpt++); // on teste l'ensemble des cases dont la valeur est 1 (non marquée et non 0)
 
   for (j=0;j<NBY;j++)
      for (i=0;i<NBX;i++)
         if (Tab[i][j])
            Tab[i][j]--; // on enlève un a toutes les valeurs>0 car le compteur commençait à 2
 
   return 0;
}

Reply

Marsh Posté le 17-04-2001 à 02:36:53    

Vi c'est en gros ce à quoi j'avais pensé, si ce n'est que j'avais envisagé une seconde matrice pour marquer les passages à cause de l'ambiguité possible entre le 1 de la table initiale et le 1 du premier ilôt.
Mais si on démarre le compteur à 2,il n'y a en effet pas besoin.

Reply

Marsh Posté le 17-04-2001 à 17:50:27    

Donc, si je comprends bien, ce petit programme analyse tout les îlots un à un, leurs associe un numéro qui s'incrémente, qui commence à deux, et puis il enlève 1 à tous les ilots.  C'est exactement ce qu'il me faut. Merci.

Reply

Marsh Posté le 17-04-2001 à 18:34:05    

Est-ce qu'il y a moyen pour que ce programme puisse se trouver dans une seule fonction.  Genre de fonction qui reçoit un tableau en argument et qui me retournerait la visualisation de la matrice ainsi traité.

Reply

Marsh Posté le 17-04-2001 à 21:16:00    

Je voudrais que ma fonction reçoive comme argument, le nom d'un fichier.  Est-ce que c'est possible?

Reply

Marsh Posté le 17-04-2001 à 21:16:50    

Tu fais ce que tu veux avec ta fonction :D

Reply

Marsh Posté le 17-04-2001 à 21:25:09    

J'aimerais beaucoup ça, mais je ne sais pas si c'est possible de passer le nom d'un fichier en argument.
 
Soit:
 
int fonction (int nom_fichier) {
....
ifstream tableau("nom_fichier.txt" );  
 for (i=0; i<20; ++i)    
 for (j=0; j<20; ++j)
 tableau>>Tab [i][j];
 tableau.close();
 
De cette façon ça ne peut fonctionner? Est-ce qu'il y a moyen d'y parvenir, par un autre stratagème?

Reply

Marsh Posté le 17-04-2001 à 21:28:13    

En effet comme ça, ça va être dur.
En fait faudrait que t'achètes un bouquin de base sur le C ou C++ parce qu'autrement t'y arriveras jamais.
C'est comme les maths, pour être autonome, faut suivre et comprendre un cours, faire faire les exos sur le net ne sert à rien.

Reply

Marsh Posté le 18-04-2001 à 09:21:21    

J'ai p'tet pas tout bien compris... (j'ai p'tet pas bien cherche non plus :D) mais il y a qq chose qui me choque profondement... pas vous ?
 
vous faites des acces a des elements qui n'existent pas dans la matrice  
tab[i-1]... et quand i vaut 0 ?
tab[i+1]... et quand i vaut 19 ?
 
c'est aussi pour cela que ca ne marchait pas dans la premiere version !

Reply

Marsh Posté le 18-04-2001 à 12:31:40    

BENB a écrit a écrit :

 
vous faites des acces a des elements qui n'existent pas dans la matrice  
tab[i-1]... et quand i vaut 0 ?
tab[i+1]... et quand i vaut 19 ?




Où ça ?

Reply

Marsh Posté le 18-04-2001 à 13:34:59    

au fait, c'est pourquoi que tu dois faire ca mistigri101 ?
C'est comme ca ?

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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