Supprimer les doublons d'un tableau en C

Résolu/Fermé
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 - 17 nov. 2010 à 19:38
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 - 18 nov. 2010 à 20:24
Bonjour,

Je dois programmer une fonction qui permet de "compacter" un tableau.
par exemple, si il contient 3 3 1 4 2 1 ca deviendra 3142 (l'odre n'est pas important).

J'utilise une fonction"supprimer" pour supprimer une case du tableau.

Pour parcourir le tableau, j'utilise un itérateur qui DOIT être remis sur la première case après chaque appel de la fonction "supprimer".

Je me casse la tête dessus depuis plusieurs heures...

quelqu'un pourrait-il m'aider ? c'est urgent ! merci beaucoup d'avance !
A voir également:

8 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
17 nov. 2010 à 19:46
Fait voir ce que tu as commencé à faire pour mieux t'aider, en particulier voir la fonction supprimer, et ton itérateur même si je pense que tu utilises mal ce terme...
0
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 272
Modifié par prypiat_child le 17/11/2010 à 23:04
A vrai dire on m'a donné un fichier .o qui contenait les fonctions suivantes :
-supprimer l'élément (pointé par l'itérateur j'entends)
-ajouter un élément
-avancer l'itérateur
-le remettre au début
-récupérer l'élément pointé.
-tester si l'itérateur est à la fin de l'ensemble (cad après le dernier élément)

et qui contenait aussi une définition de structure qui contient cet itérateur ainsi qu'un ensemble de nombres (je n'ai pas plus de précisions). Je sais juste qu'on est obligé de remettre l'itérateur au début après l'appel de "ajouter" ou "supprimer", sans quoi ça plante.

Les 4 fonctions sont bien entendu fonctionnelles....

La fonction de compactage utilise donc ces 4 fonctions sans se soucier de leur contenu.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
17 nov. 2010 à 23:13
C'est peut-être bien un itérateur finalement... ça expliquerait pourquoi tu dois le réinitialiser après chaque modification du contenu.
Par contre tes fonctions ne sont très certainement pas fonctionnelle, pas en C !
0
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 272
Modifié par prypiat_child le 17/11/2010 à 23:06
Voici ma version de la fonction (qui ne fonctionne pas donc)

void ensembleCompacter(Ensemble self)
{
int j;
int NbElements;
int nbFoisAvance = 0;
for(ensembleIterateurDebut(self);ensembleIsIterateurFin(self) == false; ensembleIterateurAvancer(self))
{

NbElements = ensembleGetElementNbOccurrences(self, ensembleGetIterateurElement(self));
if(NbElements > 1)
{
ensembleSupprimerElement(self, ensembleGetIterateurElement(self));
ensembleIterateurDebut(self);
for (j=0;j<nbFoisAvance;j++)
{
ensembleIterateurAvancer(self);
}

}

nbFoisAvance++;
}

ensembleIterateurDebut(self);
}

(désolé pour l'indentation^^)
"Si Satan aime le jazz, alors il doit écouter Naked City, confortablement installé
sur son canapé en cuir humain."
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
17 nov. 2010 à 23:31
Est-ce que tu as un header .h avec les prototypes des fonctions ?

Je trouve bizarre ton utilisation de ensembleGetIterateurElement(self)
En fait j'ai l'impression que tu confonds ensembles et itérateurs sur ces ensembles

Remarque :
ensembleIsIterateurFin(self) == false // <=> !ensembleIsIterateurFin(self)
Pour l'indentation utilises les balises de code, c'est fait pour ça !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 272
Modifié par prypiat_child le 18/11/2010 à 19:25
Cette fonction "ensembleGetIterateurElement(self)" permet de renvoyer l'élément de l'ensemble pointé par l'itérateur. Elle fait partie du fichier .o.

Voici le fichier .h :

/* 
 * Ensemble avec multiplicité d'un élément possible 
 */ 

#ifndef ENSEMBLE_H 
#define ENSEMBLE_H 

#include <stdio.h> 
#include <stdbool.h> 

typedef int TElement; 
#define TElementFormat "%d" 

struct EnsembleP; 
typedef struct EnsembleP * Ensemble; 
typedef const struct EnsembleP * constEnsemble; 

//Constantes 

extern constEnsemble ENSEMBLE_VIDE; 
extern constEnsemble ENSEMBLE_ZERO; 

int ensembleGetNbCrees(); 
int ensembleGetNbActifs(int cardinal); 

//Constructeurs et destructeur 

Ensemble ensembleCreerDefaut(); 
Ensemble ensembleCreerCopie(constEnsemble source); 
Ensemble ensembleCreerDeFichier(FILE *file); 
void ensembleDetruire(Ensemble *self); 

void ensembleAffectation(Ensemble self, constEnsemble source); 

bool ensembleEgal(constEnsemble self, constEnsemble rhs); 
bool ensembleDifferent(constEnsemble self, constEnsemble rhs); 

int ensembleGetCardinal(constEnsemble self); 
bool ensembleAppartient(constEnsemble self, TElement elt); 
int ensembleGetElementNbOccurrences(constEnsemble self, TElement elt); 
void ensembleAjouterElement(Ensemble self, TElement elt); 
void ensembleSupprimerElement(Ensemble self, TElement elt); 

void ensembleIterateurDebut(constEnsemble self); 
void ensembleIterateurAvancer(constEnsemble self); 
bool ensembleIsIterateurFin(constEnsemble self); 
TElement ensembleGetIterateurElement(constEnsemble self); 

void ensembleUnion1(Ensemble self,constEnsemble lhs, constEnsemble rhs); 
void ensembleUnion2(Ensemble self, constEnsemble rhs); 
void ensembleSoustraction1(Ensemble self,constEnsemble lhs, constEnsemble rhs); 
void ensembleSoustraction2(Ensemble self, constEnsemble rhs); 
void ensembleIntersection1(Ensemble self,constEnsemble lhs, constEnsemble rhs); 
void ensembleIntersection2(Ensemble self, constEnsemble rhs); 

void ensembleAfficher(constEnsemble self, FILE *file,const char *avant, const char *apres); 
void ensembleSauver(constEnsemble self, FILE *file); 
void ensembleCompacter(Ensemble self); 
void ensembleVider(Ensemble self); 

#endif


Le .o contient le constructeur par défaut, le destructeur, les fonctions qui utilisent directement l'itérateur, et les fonctions "ajouter" et "supprimer".

J'ai déjà écrit toutes les fonctions et tout fonctionne sans souci, excepté cette "ensembleCompacter".
"Si Satan aime le jazz, alors il doit écouter Naked City, confortablement installé
sur son canapé en cuir humain."
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
18 nov. 2010 à 19:54
Si j'ai bien compris tu ne peux utiliser qu'un itérateur à la fois, or pour faire ça correctement tu devrais au moins en utiliser deux en parallèles.

Je pense que le mieux avec cette librairie c'est d'utiliser un ensemble temporaire temp que tu rempliras au fur et à mesure avec ensembleAjouterElement(temp,elt).
Les éléments elt à ajouter étant bien évidemment ceux de ton ensemble self de départ que tu parcours avec ton itérateur et que tu ajoutes tous sans exception (comme c'est un ajout ensembliste, il ne devrait pas y avoir de doublons dans le résultat).
Et à la fin tu utiliseras ensembleAffectation(self,temp) pour remplacer ton ensemble de départ par l'ensemble temporaire qui ne contient pas de doublons.
0
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 272
18 nov. 2010 à 20:04
OK, merci ! j'essaie ca tout de suite et je te tiens au courant...
0
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 272
18 nov. 2010 à 20:08
Quand je fais ca, ben ca compresse pas... self est inchangé en sortie de la fonction.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
18 nov. 2010 à 20:20
C'est donc que l'opération ensembleAjouterElement n'est pas ensembliste (sic !)
Dans ce cas, définis une fonction ensembliste d'ajout, et utilises cette fonction à la place.

Par exemple :
void ajoutEnsembliste(Ensemble self, TElement elt)
{
   ensembleUnion1(self,ensembleAjouterElement(ensembleCreerDefaut(),elt));
}
0
prypiat_child Messages postés 1343 Date d'inscription vendredi 30 octobre 2009 Statut Membre Dernière intervention 10 avril 2014 272
18 nov. 2010 à 20:24
Je viens de trouver !

void ensembleCompacter(Ensemble self)
{
    Ensemble temp = ensembleCreerDefaut();

    for(ensembleIterateurDebut(self);ensembleIsIterateurFin(self) == false; ensembleIterateurAvancer(self))
    {
		    if(ensembleGetElementNbOccurrences(temp, ensembleGetIterateurElement(self))==0)
                ensembleAjouterElement(temp, ensembleGetIterateurElement(self));
    }

    ensembleIterateurDebut(self);

    ensembleAffectation(self,temp);

    ensembleDetruire(&temp);
}


Bon je trouve ca un peu "dégueu" de créer un ensemble temporaire mais ca marche donc^^

Merci pour ton aide !
0