Extraire 500 mots uniques d'un fichier

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Marc56
Messages : 2199
Inscription : sam. 08/févr./2014 15:19

Extraire 500 mots uniques d'un fichier

Message par Marc56 »

Je cherche à extraire 500 mots uniques d'un fichier.
Pour cela, j'ai eut l'idée d'utiliser une Map (uniquement les clé), puisqu'une map empêche de créer deux fois la même.
(Je ne parcours pas tout le fichiers: dès que j'en ai 500 je quitte)
Edit: Version 2 (tri des mots)

Code : Tout sélectionner

; Extraire 500 mots uniques
; Commence et fini par une lettre
; Contient au moins 5 caractères (A à Z majuscules/minuscules, point, signe moins)

Test_File$ = ProgramParameter(0)
If Test_File$ = "" 
    MessageRequester("Error", "Please provide a filename in compiler parameter")
    End
EndIf

If Not OpenFile(hFile, Test_File$)
     Debug "Fichier non chargé"
     End
EndIf
Debug "Lecture..."
While Not Eof(hFile)
     Txt$ = ReadString(hFile, #PB_Ascii | #PB_File_IgnoreEOL)
Wend
CloseFile(hFile)
Debug "Taille: " + FormatNumber(Len(Txt$), hFile) + " caractères"

If CreateRegularExpression(0, "\b([A-Za-z][A-Za-z-.]{3,}[A-Za-z])\b")
    Debug "RegEx OK"
Else
    Debug "RegEx KO" : End
EndIf

NewMap Words$()

If ExamineRegularExpression(RegEx, Txt$)
    While NextRegularExpressionMatch(RegEx) 
        ;i + 1
        Tmp_Word$ = RegularExpressionGroup(RegEx, 1)
        Words$(Tmp_Word$) = ""; "Word_" + RSet(Str(i), 3, "0")  
        If MapSize(Words$()) >= 500 : Break : EndIf
    Wend    
    FreeRegularExpression(RegEx)
EndIf

; ShowVariableViewer()
; CallDebugger

; Sort keys
NewList Sorted_Words$()
ForEach Words$()
    AddElement(Sorted_Words$())
    Sorted_Words$() = MapKey(Words$())
Next
SortList(Sorted_Words$(), #PB_Sort_Ascending)

Words_FileName$ = GetTemporaryDirectory() + "Words.txt"
CreateFile(hFile, Words_FileName$)
ForEach Sorted_Words$()
    WriteStringN(hFile, Sorted_Words$())
Next
CloseFile(hFile)
RunProgram(Words_FileName$)

End
Question: est-ce une bonne idée ou peut-on faire mieux (plus simple) ?
J'ai pensé à une base SQLite en mémoire et un SELECT DISTINCT, mais je ne pense pas que soit plus rapide pour 500 mots.

:wink:
Shadow
Messages : 1413
Inscription : mer. 04/nov./2015 17:39

Re: Extraire 500 mots uniques d'un fichier

Message par Shadow »

Salut,

Les Maps sont un excellent moyen en effet, c'est instantané avec la clef.
Je doute qu'il est plus rapide que les Maps...
Processeur: Intel Core I7-4790 - 4 Cœurs - 8 Thread: 3.60 Ghz.
Ram: 32 GB.
Disque: C: SDD 250 GB, D: 3 TB.
Vidéo: NVIDIA GeForce GTX 960: 2 GB DDR5.
Écran: Asus VX248 24 Pouces: 1920 x 1080.
Système: Windows 7 64 Bits.

PureBasic: 5.60 x64 Bits.
Avatar de l’utilisateur
Micoute
Messages : 2585
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Extraire 500 mots uniques d'un fichier

Message par Micoute »

Si, les tableaux à unique dimension.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9546
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Extraire 500 mots uniques d'un fichier

Message par Ar-S »

@Micoute
Dans un tableau tu peux bien stocker autant de fois le même mots que tu veux.. L'intérêt de la MAP est justement de n'accepter qu'une occurrence par clé.
Dans ton tableau si tu entres les mots "tata,toto,titi,toto,tutu" tu vas te retrouver avec un tableau de 0,1,2,3,4 avec un doublon..
Avec les maps tu auras 4 clés sans le second "toto".
la doc a écrit :il n'est pas possible d'avoir deux éléments distincts avec la même clef
Petit exemple concis:

Code : Tout sélectionner

Global.s Texte = "toto titi tutu toto tata"
NewMap mot.s()

For i = 1 To CountString(texte," ") +1
  mot( StringField(Texte,i," ") ) = ""
Next

ForEach Mot()
  Debug MapKey (mot())
Next

Version avec une macro

Code : Tout sélectionner

; Initialisation
Texte.s = "toto titi tutu toto tata"
NewMap mot.s()

; Macro si on veut s'en reservir...
Macro CreateMapKeys(strings,delimiteur,mapname)
  For i = 1 To CountString(strings,delimiteur) +1
  mapname( StringField(strings,i,delimiteur) ) = ""
Next
EndMacro


; Execution Programme
CreateMapKeys(texte," ",mot)

; Résultat
ForEach Mot()
  Debug MapKey (mot())
Next

@Marc56 je ne sais pas s'il y a plus rapide mais c'est judicieux d'utiliser les clés des maps.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Micoute
Messages : 2585
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Extraire 500 mots uniques d'un fichier

Message par Micoute »

Je suis d'accord sur ce principe, mais Shadow a dit "Je doute qu'il y est plus rapide que les Maps", c'est pourquoi j'ai fait cette réponse.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Répondre