Accueil
Accueil Le Club Delphi Kylix C C++ Java J2EE DotNET & C# Visual Basic Access Pascal Dev Web PHP ASP XML UML SQLSGBD Windows Linux Autres
logo

precedent    sommaire    suivant   


Auteur : Flype
Auteur : Comtois
Version : 20/02/2008
Compteur de mots dans un texte avec un arbre binaire
Pour cela on utilise un arbre binaire. L'arbre contient un noeud pour chaque mot, et chaque noeud contient une variable pour stocker :

  • Le mot
  • Le nombre d'apparitions du mot
  • Un pointeur vers le noeud suivant à gauche
  • Un pointeur vers le noeud suivant à droite
A partir de n'importe quel noeud , le sous arbre de gauche ne contient que des mots de valeurs inférieures au mot contenu dans le noeud, et le sous arbre de droite ne contient que des mots de valeurs supérieures.

;- purebasic 4.0

Structure Noeud
  mot.s
  compteur.l
  *Gauche.Noeud
  *Droit.Noeud
EndStructure

Procedure.s Affiche(*Noeud.Noeud, minimum.l)
  Protected resultat.s
  If *Noeud
    resultat + Affiche(*Noeud\Gauche, minimum)
    If *Noeud\compteur >= minimum
      resultat + RSet(Str(*Noeud\compteur), 4, "0") + " : " + *Noeud\mot + #CRLF$
    EndIf
    resultat + Affiche(*Noeud\Droit, minimum)
  EndIf
  ProcedureReturn resultat
EndProcedure
Procedure.l Arbre(*Noeud.Noeud, mot.s)
  If *Noeud
    If mot = *Noeud\mot
      *Noeud\compteur + 1
    ElseIf mot < *Noeud\mot
      *Noeud\Gauche = Arbre(*Noeud\Gauche, mot)
    Else
      *Noeud\Droit = Arbre(*Noeud\Droit, mot)
    EndIf
  Else
    *Noeud = AllocateMemory(SizeOf(Noeud))
    If *Noeud
      *Noeud\mot = mot
      *Noeud\compteur = 1
    EndIf
  EndIf
  ProcedureReturn *Noeud
EndProcedure
Procedure.l Analyse(texte.s, minimum.l)
  Protected *arbre, mot.s, nbcar.l, *txt.Character = @texte
  While *txt\c
    Select *txt\c
      Case ' ', '.', ',', ';', ' ', '(', ')', #TAB, #CR, #LF
        If nbcar >= minimum
          *arbre = Arbre(*arbre, mot)
        EndIf
        mot = ""
        nbcar = 0
      Default
        mot + Chr(*txt\c)
        nbcar + 1
    EndSelect
    *txt + SizeOf(Character)
  Wend
  ProcedureReturn *arbre
EndProcedure
Procedure.s Texte(fichier.s)
  Protected texte.s
  If ReadFile(0, fichier)
    texte = Space(Lof(0))
    ReadData(0, @texte, Lof(0))
    CloseFile(0)
  EndIf
  ProcedureReturn texte
EndProcedure

;- affiche les mots de 4 caractères minimum, présents au minimum 20 fois dans le texte.

MessageRequester("Résultat", Affiche(Analyse(Texte(#PB_Compiler_Home+"Compilers/APIFunctionListing.txt"), 4), 20))

Auteur : Comtois
Version : 20/02/2008
Construction d'un quadtree

;03/02/07
;Exemple de construction d'un quadtree avec répartition des objets
;Vous pouvez changer la valeur de #QuadObjet pour constater le changement de répartition
;

Structure s_Objet
  x.l
  y.l
  Rayon.l
EndStructure

Structure s_Boite
  Xmini.l
  Ymini.l
  Xmaxi.l
  Ymaxi.l
EndStructure

Structure s_QuadTree
  Depth.l
  Boite.s_Boite
  NbObjets.l
  *Liste.s_Objet 
  *Fils.s_QuadTree[4]
EndStructure

;-Declaration des procédures
Declare ConstructionQuadTree(*Noeud.s_QuadTree, *Boite.s_Boite, *Liste.s_Objet, NbObjets)
Declare RenderQuadtree(*this.s_QuadTree)

;-Variables de configuration
#NbObjets  =  50           ; Nombre d'objets dans la scène
#QuadSize  = 599          ; Taille initiale du quadtree
#QuadDepth = 5            ; Profondeur du quadtree (nb de fois qu'on decoupe le plan)
#QuadObjet = 1            ; Nombre d'objets maxi par Noeud
#Rayon     = 3            ; Rayon d'un objet

Dim ListeInitiale.s_Objet(#NbObjets-1)   
Define.s_QuadTree NoeudInitial
Define.s_Boite BoiteInitiale

;-Initialise une boite
Procedure InitBoite(*this.s_Boite, Xmini, Xmaxi, Ymini, Ymaxi)
  With *this
    \Xmini = Xmini 
    \Xmaxi = Xmaxi
    \Ymini = Ymini
    \Ymaxi = Ymaxi
  EndWith
EndProcedure

;Création d'une liste d'objets (sphères dans cet exemple)
Procedure CreationListe(this.s_Objet(1))
  For i=0 To #NbObjets-1
    this(i)\x = Random(#QuadSize-#Rayon)
    this(i)\y = Random(#QuadSize-#Rayon)
    this(i)\Rayon = #Rayon   
  Next i
EndProcedure

;Construction du quadtree avec répartition des objets
Procedure ConstructionQuadTree(*Noeud.s_QuadTree, *Boite.s_Boite, *Liste.s_Objet, NbObjets)
  Define.s_Boite BoiteFils
  Define.s_Objet *ListeFils, *Ptr
  ;Define.s_Vecteur CentreBoite, DemiDimensionBoite
  Define.s_QuadTree    *PtrF
  Define.l x, y, z, i, t, NbObjetsFils
   
  NewList Liste.s_Objet()
 
  *Noeud\Boite\Xmini = *Boite\Xmini
  *Noeud\Boite\Xmaxi = *Boite\Xmaxi
  *Noeud\Boite\Ymini = *Boite\Ymini
  *Noeud\Boite\Ymaxi = *Boite\Ymaxi

  ; Le noeud peut être partagé ?
  If NbObjets > #QuadObjet And *Noeud\Depth < #QuadDepth

    ;On répartit les objets dans les noeuds fils

    For y = 0 To 1
      For x = 0 To 1
       
        ;No du fils
        i = (y << 1) | x
       
        ;Boite englobante du fils i
        BoiteFils\Xmini = (1.0 - x / 2.0) * *Boite\Xmini  + x / 2.0 * *Boite\Xmaxi
        BoiteFils\Xmaxi = BoiteFils\Xmini + (*Boite\Xmaxi - *Boite\Xmini) / 2.0
        BoiteFils\Ymini = (1.0 - y / 2.0) * *Boite\Ymini  + y / 2.0 * *Boite\Ymaxi
        BoiteFils\Ymaxi = BoiteFils\Ymini + (*Boite\Ymaxi - *Boite\Ymini) / 2.0 
         
        *Ptr = *Liste
       
        ClearList(Liste())
         
        For t = 1 To NbObjets

          ; Calcul les objets en collision avec la boite du fils i
          If *Ptr\x > BoiteFils\Xmini And *Ptr\x < BoiteFils\Xmaxi And *Ptr\y > BoiteFils\Ymini And *Ptr\y < BoiteFils\Ymaxi
             
            AddElement(Liste())

            CopyMemory(*Ptr, Liste(), SizeOf(s_Objet))
           
          EndIf
         
          *Ptr + SizeOf(s_Objet)
         
        Next t

        NbObjetsFils = CountList(Liste())
       
        *ListeFils = #Null
       
        If NbObjetsFils 
         
          *ListeFils = AllocateMemory(SizeOf(s_Objet) * NbObjetsFils)
          *Ptr = *ListeFils
         
          ForEach Liste()
            CopyMemory(Liste(), *Ptr, SizeOf(s_Objet))
            *Ptr + SizeOf(s_Objet)
          Next
         
        EndIf

        ;Ajoute un Noeud
        *Noeud\Fils[i]=AllocateMemory(SizeOf(s_QuadTree))
     
        *PtrF = *Noeud\Fils[i]
        *PtrF\Depth = *Noeud\Depth + 1
     
        ConstructionQuadTree(*Noeud\Fils[i], @BoiteFils, *ListeFils, NbObjetsFils)
       
      Next x
    Next y

  Else
 
    ; Affecte la liste au noeud en cours
    *Noeud\Liste = *Liste
    *Noeud\NbObjets = NbObjets

  EndIf
 
EndProcedure

; Rendu du Quadtree
Procedure RenderQuadtree(*this.s_QuadTree)
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(*this\Boite\xmini,*this\Boite\ymini,*this\Boite\xmaxi-*this\boite\xmini,*this\Boite\ymaxi-*this\Boite\ymini,#White)
  If *this\Liste
    *Ptr.s_Objet = *this\Liste
    For i = 0 To *this\NbObjets-1
      Circle(*Ptr\x,*Ptr\y, *Ptr\Rayon,#Red)
      *Ptr + SizeOf(s_Objet)
    Next i
  EndIf 
  For y = 0 To 1
    For x = 0 To 1
      i = (y << 1) | x
      If *this\Fils[i]         
        RenderQuadtree(*this\Fils[i])
      EndIf
    Next x
  Next y
EndProcedure 

;*******************
;- Exemple         *
;*******************
If InitSprite()=0 Or InitMouse()=0 Or InitKeyboard()=0
  End
EndIf
 
OpenScreen(800,600,32,"Quadtree Demo")

InitBoite(@BoiteInitiale, 0, #QuadSize, 0, #QuadSize)
CreationListe(ListeInitiale())
ConstructionQuadTree(@NoeudInitial, @BoiteInitiale, ListeInitiale(), #NbObjets)

Repeat

  ClearScreen(#Black)
 
  ExamineKeyboard()
  ; Rendu du quadtree
  StartDrawing(ScreenOutput())
    RenderQuadtree(@NoeudInitial)
  StopDrawing()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

Auteur : Flype
Version : 09/03/2008
Formatage d'un nombre (StrNum)

Il s'agit de 2 fonctions (une pour les Quads, une pour les Doubles) pour formater un nombre comme ceci :

StrNumQ(-1234567) donne "-1,234,567"
StrNumD(-1234.5678) donne "-1,234.567"

Voici une solution qui ne fait pas appel à l'API windows (donc utile aussi sous Linux ou Mac).

Récursivité, quand tu nous tiens...

; StrNumQ(Number.q [, Grouping.l [, ThousandSep.s]])
; StrNumD(Number.d [, Grouping.l [, ThousandSep.s [, DecimalSep.s [, NumDigits.l]]]])

EnableExplicit

Procedure.s StrNumQ(Number.q, Grouping.l = 3, ThousandSep.s = ",", Reserved1.s = "", Reserved2.s = "", Reserved3.l = 0)
  If Not Reserved3
    ProcedureReturn StrNumQ(0, Grouping, ThousandSep, StrQ(Number), "", 1)
  EndIf
  If Not Reserved1 Or Reserved1 = "-"
    ProcedureReturn Reserved1 + Reserved2
  EndIf
  If Reserved3 = 2
    Reserved2 = ThousandSep + Reserved2
  EndIf
  ProcedureReturn StrNumQ(0, Grouping, ThousandSep, Left(Reserved1, Len(Reserved1)-Grouping), Right(Reserved1, Grouping) + Reserved2, 2)
EndProcedure

Procedure.s StrNumD(Number.d, Grouping.l = 3, ThousandSep.s = ",", DecimalSep.s = ".", NumDigits.l = 4, Reserved1.s = "", Reserved2.s = "", Reserved3.l = 0)
  If Not Reserved3
    ProcedureReturn StrNumD(0, Grouping, ThousandSep, "", 0, StringField(StrD(Number), 1, "."), DecimalSep + StringField(StrD(Number, NumDigits), 2, "."), 1)
  EndIf
  If Not Reserved1 Or Reserved1 = "-"
    ProcedureReturn Reserved1 + Reserved2
  EndIf
  If Reserved3 = 2
    Reserved2 = ThousandSep + Reserved2
  EndIf
  ProcedureReturn StrNumD(0, Grouping, ThousandSep, "", 0, Left(Reserved1, Len(Reserved1)-Grouping), Right(Reserved1, Grouping) + Reserved2, 2)
EndProcedure

Debug "StrNumQ()" ;{
Debug StrNumQ(1234567890)
Debug StrNumQ(123456789)
Debug StrNumQ(12345678)
Debug StrNumQ(1234567)
Debug StrNumQ(123456)
Debug StrNumQ(12345)
Debug StrNumQ(1234)
Debug StrNumQ(123)
Debug StrNumQ(12)
Debug StrNumQ(1)
Debug StrNumQ(0)
Debug StrNumQ(-1)
Debug StrNumQ(-12)
Debug StrNumQ(-123)
Debug StrNumQ(-1234)
Debug StrNumQ(-12345)
Debug StrNumQ(-123456)
Debug StrNumQ(-1234567)
Debug StrNumQ(-12345678)
Debug StrNumQ(-123456789)
Debug StrNumQ(-1234567890)
Debug ""
;}

Debug "StrNumD()" ;{
Debug StrNumD(1234567890.12345)
Debug StrNumD(123456789.12345)
Debug StrNumD(12345678.12345)
Debug StrNumD(1234567.12345)
Debug StrNumD(123456.12345)
Debug StrNumD(12345.12345)
Debug StrNumD(1234.12345)
Debug StrNumD(123.12345)
Debug StrNumD(12.12345)
Debug StrNumD(1.12345)
Debug StrNumD(0.12345)
Debug StrNumD(-1.12345)
Debug StrNumD(-12.12345)
Debug StrNumD(-123.12345)
Debug StrNumD(-1234.12345)
Debug StrNumD(-12345.12345)
Debug StrNumD(-123456.12345)
Debug StrNumD(-1234567.12345)
Debug StrNumD(-12345678.12345)
Debug StrNumD(-123456789.12345)
Debug StrNumD(-1234567890.12345)
Debug ""
;}

End

ce qui revient au même que la fonction Win32 dédiée :

Procedure.s StrNum(Number.s, decimal.l = 2) ; Formats a number string as a number string customized for a specified locale.
  Protected result.s, fmt.NUMBERFMT
  fmt\NumDigits     = decimal ; Specifies the number of fractional digits.
  fmt\LeadingZero   = 0       ; Specifies whether to use leading zeroes in decimal fields.
  fmt\Grouping      = 3       ; Specifies the size of each group of digits to the left of the decimal.
  fmt\lpDecimalSep  = @"."    ; Pointer to a null-terminated decimal separator string.
  fmt\lpThousandSep = @" "    ; Pointer to a null-terminated thousand separator string.
  fmt\NegativeOrder = 1       ; Specifies the negative number mode (LOCALE_INEGNUMBER).
  result = Space(GetNumberFormat_(0, 0, Number, fmt, 0, 0))
  GetNumberFormat_(0, 0, Number, fmt, @result, Len(result))
  ProcedureReturn result
EndProcedure

Macro StrNumL(Number) : StrNum(Str (Number), 0) : EndMacro
Macro StrNumF(Number) : StrNum(StrF(Number), 4) : EndMacro
Macro StrNumD(Number) : StrNum(StrD(Number), 8) : EndMacro
Macro StrNumQ(Number) : StrNum(StrQ(Number), 0) : EndMacro

Debug StrNumD(-112233445566.778899)

precedent    sommaire    suivant   

Consultez les autres pages sources


Les sources présentés sur cette pages sont libre de droits, et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright ©2008  Developpez LLC. Tout droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérets. Cette page est déposée à la SACD.

Vos questions techniques : forum d'entraide Accueil - Publiez vos articles, tutoriels, cours et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones. Nous contacter - Copyright 2000..2005 www.developpez.com