Comment feriez-vous ?
Comment feriez-vous ?
Bon,
Voilà le petit problème que je vous pose pour voir les différentes manières de faire.
On a une liste chainée basée sur une structure de disons 3 éléments.
Nom
Prenom
Age
Imaginons que nous ayons rempli cette liste chainée avec des élément, peu importe combien (5, 100, 10000 etc)
Comment feriez-vous pour supprimer chaque élément de la liste contenant le même prénom par exemple.
C'est pas une colle, c'est juste pour voir les différentes manières
Voilà le petit problème que je vous pose pour voir les différentes manières de faire.
On a une liste chainée basée sur une structure de disons 3 éléments.
Nom
Prenom
Age
Imaginons que nous ayons rempli cette liste chainée avec des élément, peu importe combien (5, 100, 10000 etc)
Comment feriez-vous pour supprimer chaque élément de la liste contenant le même prénom par exemple.
C'est pas une colle, c'est juste pour voir les différentes manières
... et tu te retrouves avec une fiche dont Fiche(x)\Nom.s est vide, mais la fiche est toujours là, avec le prénom, et l'age. Pas vraiment utile, d'après moi!si Fiche(x)\Nom.s = "Tersaken" alors Fiche(x)\Nom.s = ""
Fais plutôt DeleteElement(), ça t'enlève le nom, le prènom, et l'age, et ça te mets à jour les index.
Chris

Si j'ai bien compris , il ne faut pas donner de prénom à l'avance , il s'agit de supprimer tous les éléments qui n'ont pas un prénom unique ?si Fiche(x)\Nom.s = "Tersaken" alors Fiche(x)\Nom.s = ""
Dans un bouquin sur le c , j'ai lu un truc qui s'apparente à ton problème .
Il s'agit de compter le nombre d'apparitions de chaque mot dans un fichier texte ( dans ton cas , ça pourrait être de chaque prénom ).
et la solution proposée utilise un arbre binaire pour classer les mots ( ou les prénoms ) .
une fois le classement fait , tu peux savoir quels sont les éléments de ta liste à supprimer car dans ton arbre tu sauras si un prénom est unique ou pas .
Car c'est bien de ça qu'il s'agit ? supprimer les doublons et plus ?
Les arbres ,on en a besoin pour de nombreuses choses ,depuis le temps que je me dis que c'est le sujet à bosser , je vais le faire cette fois ci

Dernière modification par comtois le ven. 26/mars/2004 21:38, modifié 2 fois.
Ben alors Denis, faudrait mieux expliquer
Parce que moi, ce que je comprends, c'est qu'il faut effacer tous les éléments qui contiennent le même prénom, donc, effacer aussi l'age, et le nom, et pas seulement le prénom!
Par exemple, en supposant que chaque élément de la liste (Nom + Prénom + Age) soit une fiche dans un agenda, il faut effacer la fiche.
C'est ça ???
Chris

Parce que moi, ce que je comprends, c'est qu'il faut effacer tous les éléments qui contiennent le même prénom, donc, effacer aussi l'age, et le nom, et pas seulement le prénom!
Par exemple, en supposant que chaque élément de la liste (Nom + Prénom + Age) soit une fiche dans un agenda, il faut effacer la fiche.
C'est ça ???
Chris

-
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
ma première solution est de faire pour chaque element de la liste une recherche dans toute la liste pour savoir le même prénom existe et à chaque fois qu'il existe, on le supprime mais c'est plutot barabre.
en un peu mieux, j'ai de trier ta liste par prénom et ensuite de la parcourir en supprimant tous les éléments qui ont le même prénom que l'élément précédent. mais pour faire un trie, il faut d'abord recopier ton bazar dans une liste normal obtenu avec un Dim Liste.struturemachin(CountList())
en un peu mieux, j'ai de trier ta liste par prénom et ensuite de la parcourir en supprimant tous les éléments qui ont le même prénom que l'élément précédent. mais pour faire un trie, il faut d'abord recopier ton bazar dans une liste normal obtenu avec un Dim Liste.struturemachin(CountList())
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Bon, ben moi, je pars sur mon idée, et tant pis si j'ai rien compris
Chris 

Code : Tout sélectionner
;- Je commence par remplir la liste avec des datas, parce que ça va plus vite comme ça
Structure FICHE
Nom.s
Prenom.s
Age.b ;<-- On pourrait mettre .w, mais faudrait que le mec arrive à 32767 ans :o))
EndStructure
NewList Agenda.FICHE()
Restore Noms ;- Les noms
For i = 0 To 7
AddElement(Agenda())
Read Agenda()\Nom
Next
Restore Prenoms ;- Les prénoms
For i = 0 To 7
SelectElement(Agenda(),i)
Read Agenda()\Prenom
Next
Restore Ages ;- et les Ages
For i = 0 To 7
SelectElement(Agenda(),i)
Read Agenda()\Age
Next
;- Un petit coup de debug pour voir la liste complète
ForEach Agenda()
Debug Agenda()\Nom + " " + Agenda()\Prenom + " = " + Str(Agenda()\Age) + " ans"
Next
Debug "--------------------------------------------"
Debug ""
;- On cherche les prénoms à supprimer : Jean et Jean-Philippe, mais pas Jean-René
ForEach Agenda()
If Agenda()\Prenom = "Jean" Or Agenda()\Prenom = "Jean-Philippe"
DeleteElement(Agenda())
EndIf
Next
;- Encore un p'tit coup de debug pour la route
ForEach Agenda()
Debug Agenda()\Nom + " " + Agenda()\Prenom + " = " + Str(Agenda()\Age) + " ans"
Next
DataSection
Noms:
Data.s "Lebrun", "Fernandez", "Duchmoll", "Martin", "Dupont", "Dupond", "Lefort", "Bernardeau"
Prenoms:
Data.s "Michel", "Jean-Philippe", "Bernard", "Michel", "Yannick", "André", "Jean-René", "Jean"
Ages:
Data.b 29,51,18,32,55,97,14,61
EndDataSection

Moi je pensais tout simplement à regarder quand on met une nouvelle valeur si elle est identique à une valeur déjà connue :
Je sais bien que tu as demandé si la liste est déjà faite mais quand il y a 5000 elements, la parcourir dans tous les sens prendrais des heures, alors que là on ne la parcour qu'une fois et de toute façon, il faut bien la créer la liste.
Code : Tout sélectionner
Nom.s = "Monnom"
Prenom.s = "monprenom"
Adresse.s = "Maville"
ForEach Liste()
If Liste()\Nom = Nom
If Liste()\Prenom = Prenom
If Liste()\Adresse = Adresse
Debug "Il y a déjà ce nom"
Break
EnDif
Endif
Endif
Addelement(Liste())
Liste()\Nom = Nom
Liste()\Prenom = Prenom
Liste()\Adresse = Adresse
next
Je vais mieux m'expliquer,
c'est ce que Chris a fait.
Donc par exemple si on a 10 éléments au total et que 4 on le meme prénom, on supprime ces 4 éléments, il doit donc en rester 6 qui ont un prénom différent de celui recherché.
Ce que Chris a fait c'est ce que je faisais, mais celà ne fonctionne pas corrrectement.
Voici la raison
La doc de DeleteElement dit ceci
Mais maintenant on reboucle et le foreach va sélectionner l'élément suivant et si celui en cours (donc le premier) contient également le prénom recherché il sera ignoré et ne sera pas effacé, donc cette façon ne va pas. On pourrait se dire que l'on teste ce nouvel élément mais on pourrait se retrouver dans ce cas.
J'utilise actuellement ceci
C'est bourrin mais je n'ai pas réfléchi plus que ça.
Un autre solution serait de modifier la fonction DeleteElement et ne pas la faire pointer sur l'élément suivant si c'est le premier élément.
Vous avez une autre solution ?
c'est ce que Chris a fait.
Donc par exemple si on a 10 éléments au total et que 4 on le meme prénom, on supprime ces 4 éléments, il doit donc en rester 6 qui ont un prénom différent de celui recherché.
Ce que Chris a fait c'est ce que je faisais, mais celà ne fonctionne pas corrrectement.
Voici la raison
La doc de DeleteElement dit ceci
Donc si l'élément supprimé est le premier, alors l'élément suivant est selectionné (si il y en a un). Jusque là ça va.Supprime l'élément courant de la liste spécifiée. Après l'appel de cette fonction, le nouvel élément courant est celui qui précédait l'élément supprimé. Si l'élément supprimé était le premier, alors l'élément suivant est selectionné (si il y en a un).
Mais maintenant on reboucle et le foreach va sélectionner l'élément suivant et si celui en cours (donc le premier) contient également le prénom recherché il sera ignoré et ne sera pas effacé, donc cette façon ne va pas. On pourrait se dire que l'on teste ce nouvel élément mais on pourrait se retrouver dans ce cas.
J'utilise actuellement ceci
Code : Tout sélectionner
ForEach Agenda()
If Agenda()\Prenom = "Jean" Or Agenda()\Prenom = "Jean-Philippe"
DeleteElement(Agenda())
Resetlist(Agenda()) ; --> on se remet au début de la liste et pas sur un élément
endif
Next
Un autre solution serait de modifier la fonction DeleteElement et ne pas la faire pointer sur l'élément suivant si c'est le premier élément.
Vous avez une autre solution ?
En fait olive, le problème n'est pas d'ajouter ou non l'élément mais de faire une recherche sur une valeur et de supprimer toutes les occurences dans la liste chainée.
J'ai été confronté à ce problèmedans ma librairie et je teste toujours pour voir si ca fonctionne et ça n'allait pas dans un cas précis.
Donc si vous trouvez une meilleur solution que la mienne, je prend.
J'ai été confronté à ce problèmedans ma librairie et je teste toujours pour voir si ca fonctionne et ça n'allait pas dans un cas précis.
Donc si vous trouvez une meilleur solution que la mienne, je prend.

Je vais surement défoncer une porte ouverte!
Mais le plus simple je crois, c'est de faire un tri de la liste par prénom.
Depuis le premier élement prendre le premier prénom comme référence.
Vérifier que le prénom suivant est différent :
si oui prendre ce nouveau prénom comme élément de comparaison.
sinon le détruire et vérifier avec le suivant
Ainsi de suite jusqu'à la fin de la liste !
Cela me parait tellement simple que j'ai du passé à coté du problème !

Mais le plus simple je crois, c'est de faire un tri de la liste par prénom.
Depuis le premier élement prendre le premier prénom comme référence.
Vérifier que le prénom suivant est différent :
si oui prendre ce nouveau prénom comme élément de comparaison.
sinon le détruire et vérifier avec le suivant
Ainsi de suite jusqu'à la fin de la liste !
Cela me parait tellement simple que j'ai du passé à coté du problème !



Denis
Bonne Jounée à tous
Bonne Jounée à tous