cs_philcam
Messages postés132Date d'inscriptiondimanche 12 août 2001StatutMembreDernière intervention17 octobre 2008
-
28 août 2005 à 13:34
cs_philcam
Messages postés132Date d'inscriptiondimanche 12 août 2001StatutMembreDernière intervention17 octobre 2008
-
30 août 2005 à 19:37
Salut à tous,
je suis en train de faire une routine pour traiter les fichiers PGN (parties d'échecs).
Le but serait de supprimer les commentaires des parties pour qu'elles soient plus lisibles.
Les commentaires sont dans le fichier pgn (fichier texte) entre des guillemets, exemple :
cs_philcam
Messages postés132Date d'inscriptiondimanche 12 août 2001StatutMembreDernière intervention17 octobre 2008 28 août 2005 à 16:01
Bon, finallement je me suis creusé la tête (j'avais la flemme aujourd'hui)
J'ai donc réalisé le truc avec une RichTextBox (RT)
Option Explicit
Private Sub Form_Load()
RT.LoadFile App.Path & "\test.pgn"
Dim I As Long
Dim Deb As Long
Dim Fin As Long
While Deb <> -1
Deb = RT.Find("{", I)
Fin = RT.Find("}", Deb)
If Deb <> -1 Then
RT.SelStart = Deb
RT.SelLength = Fin - Deb + 2
RT.SelRTF = ""
End If
I = Deb + 1
Wend
End Sub
C'était pas si compliqué, mais fallait se concentrer, et c'est une méthode rapide par rapport à prendre tous les caractères un par un (la RTbox le fait à notre place)
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 28 août 2005 à 14:20
Ben le plus simple, c'est de rechercher la position de chaque { auquel
il y a un } correspondant, et de supprimer le tout. Tu peux le faire en
utilisant les fonction InStr (recherche dans une chaîne), et Mid
(récupèration d'une sous-chaîne à partir d'une chaîne, de la position
de départ, et de la longueur à récupèrer).
DarK Sidious
Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
ashboody
Messages postés91Date d'inscriptionsamedi 30 mars 2002StatutMembreDernière intervention11 octobre 2005 28 août 2005 à 14:22
faire du parsage de texte en VB c'est pas forcément le plus rapide, mais une technique serait de tester chaque caractère successivement et de positionner un flag à 1 lorsque tu recontre une accolade { et de reseter se flag à 0 lorsque tu rencontre une accolage } afin de reprendre l'enregistrement du texte,
si mon algo a 2€ te conviens tant mieux
cs_philcam
Messages postés132Date d'inscriptiondimanche 12 août 2001StatutMembreDernière intervention17 octobre 2008 28 août 2005 à 15:13
Oui, j'ai pensé à ce genre de méthode mais ça va être lourd à mettre en place....
J'avais pensé aussi à ouvrir le fichier dans une richtextbox pour pouvoir mieux sélectionner automatiquement chaque partie entre les guillemets et les supprimer ensuite, par contre je ne connais pas les méthodes pour faire ça, donc si quelqu'un connait bien les richtextbox et a une idée merci.
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 28 août 2005 à 16:25
Ton code serait plus optimisé si tu avais utilisé les fonctions que je
t'ai donné ! Le code serait grosso-modo le même, sauf qu'à la place de
la fonction Find, il faut utiliser InStr, et au lieu de faire des
sélections comme tu le fait, il faudrait découper la chaîne du début à
la position de départ, et de la position de fin à la fin de la chaîne.
Avec ta méthode, il faut utiliser un RichTextBox (attention au
déploiement de l'application et les incompatibilités qui peuvent
apparaîtrent, notamment avec Win98 !!!) ce qui prend déjà bien plus de
ressources !
DarK Sidious
Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
cs_CanisLupus
Messages postés3757Date d'inscriptionmardi 23 septembre 2003StatutMembreDernière intervention13 mars 200621 28 août 2005 à 18:37
Salut, pour appuyer DARKSIDIOUS, un tit bout de code, sans parcours de la chaine et qui ressemble au tien (sans rtb) :
Dim s As String
Dim deb As Long
Dim lng As Long
Dim nFic As Integer
nFic = FreeFile
Open App.Path & "\test.pgn" For Input As #nFic
s = Input(LOF(nFic), #nFic)
Close #nFic
Do While InStr(s, "{") > 0
deb = InStr(s, "{")
lng = InStr(s, "}") + 2 - deb
s = Replace(s, Mid(s, deb, lng), "")
Loop
MsgBox s
Seule restriction, comme pour ton code, ça ne gère pas les accolades imbriquées. Je sais bien que, normalement, dans ce genre de notation ça ne doit pas arriver mais sait-on jamais ?
PS : interéressant cette variante de la Sicilienne fermée.
-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
cs_philcam
Messages postés132Date d'inscriptiondimanche 12 août 2001StatutMembreDernière intervention17 octobre 2008 29 août 2005 à 00:08
Salut,
j'essaye ton code, qui est en en train de tourner en ce moment et qui n'a pas fini son calcul pendant que j'écris.
Heureusement que j'ai supprimer la msgbox car j'imagine pas la gueule qu'elle aurait eu pour afficher des milliers de lignes
Et oui, car il y a 139 parties dans ce fichier et il pèse 931Ko.
Avec la richtextbox il met environ 15secondes (P4, 3Ghz) pour supprimer les commentaires, je sais c'est énorme mais pour l'instant c'est juste un programme pour moi, ça va qd même + vite qu'à la main
Sinon, merci pour votre aide, je vais creuser ces idées.
cs_philcam
Messages postés132Date d'inscriptiondimanche 12 août 2001StatutMembreDernière intervention17 octobre 2008 29 août 2005 à 17:41
Je suis désolé mais le fichier que je prends pour faire mes tests fait pas loin d'1Mo
Donc forcément ça prend du temps
de plus y a tellement de caractères à mettre dans "s" que 'integer' ne suffit pas, il me met "dépassement de capacité"
j'ai mis en "long" au lieu d'"integer", ça marche mais ça met + de 15 secondes.
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 29 août 2005 à 18:31
Alors après quelques petites recherches, voici le verdict : avec ta
procédure, 7,5 s de temps de traitement avec un richtextbox non visible
en mde compilé (donc traitement bien optimisé) sur un fichier de 500 Ko.
Avec la procédure que je donne dessous, 3 s (toujours en mode compilé
sinon, c'est VB qui bride la rapidité, mais reste tout de même plus
rapide que le RTB sous mode interprêté) en utilisant uniquement les
fonctions InStr et Mid. Bon ma procédure n'est pas parfaite, il reste
encore quelques petites rectif à faire sûrement pour obtenir des
résultats fiables (je sais pas si dans ton fichier il y a des saut de
lignes par exemple qui empêche mon script de bien fonctionner), mais la
rapidité y est, et le résultat est bon sans saut de ligne.
Voici le code :
Dim sText As String
Dim sFinishText As String
Dim lPosition(3) As Long
Dim iFileNumber As Integer
Let iFileNumber = FreeFile
Open App.Path & "\test.pgn" For Input As #iFileNumber
While Not EOF(iFileNumber)
Line Input #iFileNumber, sText
Let lPosition(0) = InStr(1, sText, "{")
Let lPosition(1) = InStr(1, sText, "}")
Let lPosition(2) = lPosition(0)
Let lPosition(3) = lPosition(1)
If
lPosition(0) > 0 Then Let sFinishText = sFinishText &
Left(sText, lPosition(0) - 1)
While lPosition(0) > 0 And lPosition(1) > 0
Let lPosition(2) = InStr(lPosition(0) + 1, sText, "{")
Let lPosition(3) = InStr(lPosition(2) + 1, sText, "}")
If lPosition(2) > 0 And lPosition(3) > 0 Then Let sFinishText =
sFinishText & Mid(sText, lPosition(1) + 1, lPosition(2) -
lPosition(1) - 1)
Let lPosition(0) = lPosition(2)
Let lPosition(1) = lPosition(3)
Wend
Wend
Close #iFileNumber
DarK Sidious
Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
cs_CanisLupus
Messages postés3757Date d'inscriptionmardi 23 septembre 2003StatutMembreDernière intervention13 mars 200621 29 août 2005 à 18:52
C'est vrai que le replace est pas très performant dans ce cas.
Et comme ça, avec parcours de la chaine ? :
For i = 1 To Len(s)
temp = Mid(s, i, 1)
Select Case temp
Case "{"
test = True
Case "}"
test = False
Case Else
If Not test Then s1 = s1 & temp
End Select
Next
MsgBox s1
Il risque d'y avoir des espaces en trop et il faudra faire un :
s1 = replace(s1," "," ")
Dans ce cas, c'est le s1 = s1 & temp qui prendra le plus de temps. A tester, je n'ai pas de fichier png de 1 Mo sous la main.
-------------------------------------------------
Dresseur de puces, .... normal pour un loup !?
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 29 août 2005 à 18:53
Tu es plus rapide ? Remplacer autant de Chr(164) sur un fichier de 500
Ko est plus rapide que jouer avec la fonction mid ? Je demande à voir
tout de même... ;)
C'est pour cette raison que j'ai comparé ton code avec le mien sur le
fichier de 500 Ko que j'ai reconstitué en collant plusieurs fois (pas
mal de fois quand même) ta ligne exemple.
Verdict ?
En mode compilé, richtextbox non visible : 7 s
En mode compilé, ton code : 7,5 s
En mode compilé, mon code : 2,5 s
Le replace sera toujours plus lent que plusieurs appel à Mid car il
doit rechercher la chaîne plusieurs fois et la remplacer par une
nouvelle sûrement !
DarK Sidious
Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 29 août 2005 à 18:57
Désolé canis lupus, mais tu mérite la palme de la lenteur ;)
Avec ton code, il faut 9.5 secondes pour obtenir le même résultat (mode
compilé bien entendu), c'est donc le code le plus lent. Il ne faut pas
non plus appeler trop souvent la fonction Mid quand même, faut pas
exagérer lol.
Bon allez, il faut que j'arrête là, car c'est bien beau tout cà, mais mon boulot n'avance pas :(
DarK Sidious
Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 29 août 2005 à 19:09
Ce ne sont pas tes mid qui prennent du temps daniel, c'est ton replace
de fin qui prend beaucoup de temps à s'éxécuter car il y a beaucoup de
Chr(165) à remplacer au final !
Sans le replace final, tu tombe à 5 s => tu retombe sur le problème
de canis lupus : tu appelle trop souvent la fonction Mid en parcourant
toutes la chaîne et en testant tout les caractères !
DarK Sidious
Un API Viewer (pour le VB, VB.NET, C, C# et Delphi) : www.ProgOtoP.com/popapi/