3xplo
Messages postés10Date d'inscriptionmercredi 13 décembre 2006StatutMembreDernière intervention 8 juillet 2007
-
3 juil. 2007 à 18:04
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 2021
-
11 juil. 2007 à 00:33
Bonjour,
j'ai un exercice dans lequel je dois créer un programme qui analyse un
fichier texte pour compter le nombre de "a", de "b", de "c" ..., de "z".
Le résultat doit s'afficher dans une zone de liste, chaque ligne de la
zone doit contenir une lettre et son nombre d'apparition dans le
fichier.
Donc tout ce qui est création graphique du programme jusqu'à l'appel du
fichier texte ça ne pose pas de problème, mais là je bloque pour
compter le nombre de lettre et pour l'affichage dans la zone de texte.
Si vous pouviez m'aider , me donner des conseils svp ça serai sympa car là c'est la panne sèche.
cs_Jack
Messages postés14006Date d'inscriptionsamedi 29 décembre 2001StatutModérateurDernière intervention28 août 201578 3 juil. 2007 à 20:44
Salut
Si on utilise la lettre recherchée comme borne dans un Split, on obtiendra un tableau de n+1 éléments, donc penser à retirer 1 du UBound
Que fais un Split avec les 'a' avec accent ? = problème supplémentaire
La solution de RenField semble plus adaptée.
- Dimensionner un tableau de Byte en dynamique, genre Dim aTableau() As Byte
- Lire le fichier en binaire, genre Open "C:\Mon fichier.txt" For Binary As #1
puis un redimensionnement du tableau avec la longueur du fichier :
Redim aTableau(LOF(1) - 1) ' Le -1 car les tableaux commencent à l'index 0)
puis la lecture Get #1,, aTableau
puis fermeture Close #1
Dans aTableau, tu auras les codes ASCII de chaque lettre du texte
- Préparer un tableau des scores pour chaque lettre : Dim Score(1 To 26) As Long
- Parcourrir le tableau avec une boucle For-Next de 0 à UBound(aTableau)
- Tester chaque lettre dont les codes ASCII vont de 65 à 90 (65+26) pour les majuscules et 97 à 122 pour les minuscules :
If (aTableau(r) >= 65 And aTableau(r) <= 90) Then
' Lettres standard de 'A' à 'Z'
Score(aTableau(r) - 65 + 1) = Score(aTableau(r) - 65 + 1)
ElseIf aTableau(r) >= 97 And aTableau(r) <= 122 Then
' Lettres standard de 'a' à 'z'
Score(aTableau(r) - 97 + 1) = Score(aTableau(r) - 97 + 1)
Else
' Traiter ici les lettres avec accents ...
End If
Tu récupèreras ainsi le nombre de A dans Score(1) et le nombre de Z dans Score(26)
Il y a surement d'autres méthodes ...
Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202175 3 juil. 2007 à 20:54
vu que le sujet semble intéresser...
voilà le code qui reprend les étapes que j'ai mentionnées plus tôt :
Private Sub Form_Load()
Dim xnCompteurs(25)
Dim xbData() As Byte
Dim iFile As Integer
Dim i As Long
Dim nCar As Long
iFile = FreeFile
Open "c:\hijackthis.log" For Binary Access Read As #iFile
ReDim xbData(LOF(iFile))
Get #iFile, , xbData
Close #iFile
For i = 0 To UBound(xbData)
nCar = xbData(i)
Select Case nCar
Case 65 To 90
xnCompteurs(nCar - 65) = xnCompteurs(nCar - 65) + 1
Case 97 To 122
xnCompteurs(nCar - 97) = xnCompteurs(nCar - 97) + 1
End Select
Next i
'# Ensuite, libre a toi d'en faire ce que tu veux :
For i = 0 To 25
nCar = xnCompteurs(i)
If nCar Then
Debug.Print ChrW(65 + i) & " : " nCar & " occurrence(s)"
End If
Next i
jmfmarques
Messages postés7668Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 3 juil. 2007 à 20:54
La méthode de Renfield est sans aucun doute la mieux adaptée à ce genre de problème.
Car toutes les autres entrainent un foule de traitements,
y compris celle qui consisterait à "réduire" au fur et à mesure la longueur de la chaîne à examiner, en la parcourant avec Mid et en supprimant, chaque fois, le caractère déjà compté.
Non .. vraiment : pas mieux que ce que Renfield a dit
jmfmarques
Messages postés7668Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 3 juil. 2007 à 21:52
Reste une idée à la....
1) je lis tout le fichier dans une variable toto
2) je l'épure (par replace) des caractères 10 et 13
3) j'en prends la longueur titi = len(toto)
4) je lis le 1er caractère premiercar et l'innscris en colonne 0 d'une listview
5) je supprime (par replace) ce caractère de la chaine toto et mesure la longueur de toto et inscris en colonne 1 de la listview la différence entre len(toto) et titi puis donne à titi la valeur de len(toto)
6) je reprends en 4)
et continue ainsi jusqu'à plus soif (c'est pas demain la veille en ce qui me concerne !...)
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202175 3 juil. 2007 à 22:07
*coût
on peu s'en servir, si, faut pas dire...
mais faut faire gaffe à là ou on le met... comme les Variant, faut pas cracher dessus, faut les utiliser avec parcimonie...
faut surtout, je pense, être conscient (to be aware, pour parler comme un certain JC Van Damme)
être conscient de ce qui se passe en coulisses, et choisir les algorithmes en conséquence.
je ne dit pas cela spécialement pour toi mon ami, mais pour ceux qui viendrait a lire ces quelques lignes...
ici, le probleme etait clair et simple : on comptabilise des caractères... pas besoin donc de manipuler des String :p
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202175 3 juil. 2007 à 22:13
Je répondais plus tôt sur un autre post...
le gars lisais un fichier de 50 Mo via Line Input
c'est de l'inconscience... VB va lire la chose caractère par caractère (ou plus certainement par un buffer interne, qui sera scanné par la suite)
surtout que.... ces lignes avaient une taille fixe, et connue.
Un simple calcul pouvait lui permettre de récupérer le strict nécessaire...
comme quoi, faire un code qui fonctionne n'est pas la panacée... et avant de dire que VB est lent, remettre en cause le code qu'on lui demande de traiter ^^
BruNews
Messages postés21041Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 2019 3 juil. 2007 à 22:19
Renfileld > un tableau de 256 évitera tous les 'If' ou 'Case' durant la lecture, on affiche ensuite la partie que l'on veut.
Sera nettement plus rapide sur un gros fichier.
jmfmarques
Messages postés7668Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 3 juil. 2007 à 22:26
Je vais mettre tout le monde d'accord...
Renfield a raison de dire qu'il faut toujours savoir tout bien peser avant de décider.
J'ai par exemple bien vu très récemment comment et dans quel cas de figure précis on pouvait bénéficier des avantages d'un Array généré par un "Splitting" (que je déteste pourtant) : lorsqu'il s'agit, par exemple, d'alimenter un autre contrôle.
jmfmarques
Messages postés7668Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 5 juil. 2007 à 08:13
Re....
Petite idée matinale (just for fun).
Si le text n'est pas trop long, on peut :
- 1) se servir de l'unicode (une seule fois)
- 2) aller chercher le caractère 0 final de chaque élément (caractère, donc) et le remplacer par un caractère "de séparation" (par exemple : @) (une seule fois, donc)
- 3) éclater (split) par rapport à @ ert travailler sur l'array ainsi obtenu (une seule fois, donc)
Début du mécanisme, pour mieux y voir clair :
Private Sub Command2_Click()
Dim toto As String
toto = "Voilà à quoi on peut s'amuser"
toto = StrConv(toto, vbUnicode)
toto = Replace(toto, Chr$(0), "@")
MsgBox Trim$(toto)
End Sub
3xplo
Messages postés10Date d'inscriptionmercredi 13 décembre 2006StatutMembreDernière intervention 8 juillet 2007 7 juil. 2007 à 17:55
Bonjour,
excusez-moi, je n'ai pas pu me connecter plus tôt pour problemes personnels.
Merci à tous pour votre aide.
J'ai une autre petite question pour l'affichage, j'aimerais le
dynamiser. Comment faire pour que lorsque l'on clique sur un bouton, la
zone de liste s'initialise avec 26 lignes (1 par lettre), le nombre
associé à chacune étant 0, et qu'au fur et à mesure du traitement du
fichier, la zone de liste se mette à jour ???