Page 1 sur 1

Extraire 500 mots uniques d'un fichier

Publié : sam. 11/avr./2020 10:14
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:

Re: Extraire 500 mots uniques d'un fichier

Publié : sam. 11/avr./2020 12:35
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...

Re: Extraire 500 mots uniques d'un fichier

Publié : dim. 12/avr./2020 7:58
par Micoute
Si, les tableaux à unique dimension.

Re: Extraire 500 mots uniques d'un fichier

Publié : dim. 12/avr./2020 8:57
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.

Re: Extraire 500 mots uniques d'un fichier

Publié : dim. 12/avr./2020 14:30
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.