IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Recherche dans un array


Sujet :

Delphi

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut Recherche dans un array
    bonjour à tous
    Je cherche à accélérer un peu mon code qui est très lent
    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var Buffer : array[0..2097151] of byte;//(petit fichier : 2Mo)
         PosA : Longword;
         S,S1:string;
     
    F:=TFileStream.Create(nomfichier,fmOpenRead);
    F.Read(Buffer,F.Size);
    F.Free;
     
    PosA:=0;
    s:='4442405454543031';
    While (PosA < (f.size-1)) or (s1=s) do
    begin
    s1:=inttohex(ord(buffer[PosA]),2)+inttohex(ord(buffer[PosA+1]),2)+inttohex(ord(buffer[PosA+2]),2)+inttohex(ord(buffer[PosA+3]),2)+inttohex(ord(buffer[PosA+4]),2)+inttohex(ord(buffer[PosA+5]),2)+inttohex(ord(buffer[PosA+6]),2)+inttohex(ord(buffer[PosA+7]),2);
    if s1 = s then
    begin
    // ==> action à effectué
    end;
    PosA:=PosA+1;
    end;
    Y a t-il un moyen plus rapide et plus grâcieux de faire la même chose?
    A savoir que je ne peux ouvrir ce fichier qu'avec un éditeur héxadécimal
    Merci de votre aide

  2. #2
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    alors comme ça brut de fonderie je dirais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    var
      Buffer : array[0..2097151] of byte;//(petit fichier : 2Mo)
      F: TFileStream;
      TailleBuffer, IdxCourant: Integer;
      Trouve: Boolean;
      function IsOffsetValid( Offset: Integer ): Boolean;
      begin
        Result := ( IdxCourant + Offset < TailleBuffer ) and ( ( s[1 + Offset] + s[2 + Offset] ) = IntToHex( buffer[IdxCourant+Offset], 2 ) )
      end;
    begin
      F := TFileStream.Create(nomfichier,fmOpenRead);
      try
        TailleBuffer := F.Size;
        F.Read( Buffer, TailleBuffer );
      finally
        F.Free;
      end;
     
      IdxCourant := 0;
      Trouve := False;
      s := '4442405454543031';
      while ( IdxCourant < TailleBuffer ) and not Trouve
      begin
        if IsOffsetValid( 0 ) and IsOffsetValid( 1 ) and IsOffsetValid( 2 ) and IsOffsetValid( 3 ) and IsOffsetValid( 4 ) and IsOffsetValid( 5 ) and IsOffsetValid( 6 ) and IsOffsetValid( 7 ) then
                        Trouve := True;
        Inc( IdxCourant );
      end;
    end;
    Mais bon je suis sûr qu'il y a moyen d'encore mieux faire
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  3. #3
    Modérateur
    Avatar de Rayek
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2005
    Messages
    5 235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 235
    Points : 8 504
    Points
    8 504
    Par défaut
    Quel est l'intérêt de mettre l'intégralité du fichier dans un tableau (ça limite fortement le programme) et de faire la recherche dans ce tableau alors qu'il est possible de faire la recherche directement dans le fichier.

    Code à tester, mais qui permet de se faire une idée pour la recherche.
    Enfin, moi je ferais plus de cette manière ^^

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    funtion FindPosition(NomFichier,sSearch : String) : integer;
     var
       F: TFileStream;
       Buffer : Array of Byte;
       PosA : Longword;
       sSearch,sCompare : String;
       wTemp : Byte;
       bFound : Boolean;
       i : integer;
     begin
       F:=TFileStream.Create(nomfichier,fmOpenRead);
       PosA := 0;
       bFound := False;
       SetLength(Buffer,Length(sSearch) Div 2);
     
       While (PosA <= f.Size - (Length(sSearch) Div 2)) and not bFound do
       begin
         F.Position := PosA;
         F.Read(wTemp,1);
         if Pos(sSearch,IntToHex(wTemp,2)) = 1 then
         begin
           F.Read(Buffer,Length(sSearch) Div 2);
           sCompare := '';
           for i := 0 to Length(sSearch) Div 2 do
             sCompare := sCompare + IntToHex(Buffer[i],2);
           if sSearch = sCompare then
             bFound := True
         end;
         inc(PosA);
         if bFound then
           Result := PosA -1 // retourne la position du premier caractère de la recherche
        else
          Result := -1;  // retourne -1 pour dire qu'il n'a pas trouvé
       end;
    end;
    Modérateur Delphi

    Le guide du bon forumeur :
    __________
    Rayek World : Youtube Facebook

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par Rayek Voir le message
    Code à tester, mais qui permet de se faire une idée pour la recherche.
    Enfin, moi je ferais plus de cette manière ^^
    salut
    Je viens de tester ton code, et il est plus lent que le mien .
    Merci quand même.

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Dans le code Rayek la lenteur est dû à Pos et à la concaténation de sCompare qui provoque un nombre de réallocation importante ...

    Essaye donc SearchStringInBigFile ...

    surtout que 2Mo, faut agrandir la taille de la pile par défaut dans les options de compilation ... mais bon ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    bonjour

    pourquoi chercher '4442405454543031' d'un coup ?
    => parcourir le tableau jusqu'à la première occurrence de '44', puis vérifier si l'octet suivant correspond à '42', ou au choix si la suite correspond à '42405454543031', si ce n'est pas bon on continue la recherche du '44' suivant....

    autre optimisation:
    au lieu de transformer le tableau de bytes en char (hexa) pour comparaison pourquoi ne pas faire l'inverse? cad transformer '4442405454543031' en une suite de bytes (8 conversions au lieu de 2 000 000 au pire en fin de tableau)

    la combinaison des 2 optimisations devrait donner un très bon gain de temps.
    à+

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Merci Banban2, tu viens d'expliquer le principe de ma fonction SearchString

    Sinon, greg38bj, ton code ne compile, et même il est faux, tu aurais pu mettre un produit fini pour les tests ...

    idem Rayek, F.Free manque ...

    sur un fichier de "2 042 782 octets", avec '4442405454543031' à la toute fin du fichier ...

    ChercheChaine_greg38bj : 25640 ms
    FindPositionByRayek : 21441 ms
    SearchStringInBigFileLazy : 25 ms
    lol ... bon il n'y a pas photo ...


    Tient, la variante SearchStringInBigFileLazy sans le paramètre tableau de retour qui stockent les positions ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    {* -----------------------------------------------------------------------------
    la Fonction SearchStringInBigFileLazy Permet de Chercher une Chaine dans Fichier de plus de 2Go, la fonction renvoi le nombre d'occurence
    @param FileName Chaine contenant le nom du Fichier
    @param SearchString Chaine à chercher dans le fichier
    @param Threshold Si le nombre de chaine trouvé atteind ce nombre, la Recherche s'arrête
    @param CaseSensitive Boolean True A est différent de a, False, ignore la casse (plus lent)
    @param AcceptOverlap Boolean True si le mot à chercher est une répétition cela compte les occurences qui se chevauche, False chaque lettre d'une occurence ne peut être comptabilisé qu'une seule fois (exemple on chercher coco, le fichier contient cocococo, True = 3, False = 2)
    @return Nombre d'occurence Trouvé
    ------------------------------------------------------------------------------ }
    function SearchStringInBigFileLazy(const FileName, SearchString: string; Threshold: Integer = MaxInt; CaseSensitive: Boolean = True; AcceptOverlap: Boolean = False): Integer;
    const
       BUF_SIZE: Integer = 1024;
    var
       FileToSearch: Integer;
       FileLength: Int64;
       SearchBuf: array of Char;
       iSearchBufPos, iSearch, iMark, iCountFound, iRememberFound, iReaded: Integer;
       SearchLen: Integer;
       AmtTransferred: Integer;
       LastFound: Boolean;
       UpSearchString: string;
    begin
       SearchLen := Length(SearchString);
     
       Result := 0;
       if SearchLen <= 0 then
         Exit;
     
       if not CaseSensitive then
         UpSearchString := UpperCase(SearchString);
     
       SetLength(SearchBuf, BUF_SIZE);
       iReaded := 0;
     
       FileToSearch := FileOpen(FileName, fmOpenRead);
       if FileToSearch < 0 then
         Exit;
       try
          FileLength := FileSeek(FileToSearch, 0, FILE_END);
          FileSeek(FileToSearch, 0, FILE_BEGIN);
     
          iCountFound := 0;
     
          while iReaded < FileLength do
          begin
             AmtTransferred := FileRead(FileToSearch, SearchBuf[0], BUF_SIZE); // [0] parce que c'est un tableau dynamique
             iRememberFound := iCountFound;
             iSearchBufPos := 0;
             LastFound := False;
     
             while iSearchBufPos < AmtTransferred do
             begin
                // Comparaison Octet par Octet de la chaine recherchée
                for iMark := iCountFound + 1 to SearchLen do
                begin
                   iSearch := iSearchBufPos + iMark - iRememberFound - 1;
                   if iSearch >= AmtTransferred then
                      Break;
     
                   if (CaseSensitive and (SearchBuf[iSearch] = SearchString[iMark]))
                   or (not CaseSensitive and (UpCase(SearchBuf[iSearch]) = UpSearchString[iMark])) then
                   begin
                      Inc(iCountFound);
     
                      LastFound := iCountFound >= SearchLen;
                      if LastFound then
                      begin
                         Inc(Result);
     
                         if iCountFound = Threshold then
                           Exit;
     
                         iCountFound := 0;
                         iRememberFound := 0;
                         Break;
                      end;
                   end else begin
                      iCountFound := 0;
                      iRememberFound := 0;
                      Break;
                   end;
                end;
     
                if iSearch >= AmtTransferred then
                  Break;
     
                if LastFound then
                begin
                  LastFound := False;
                  if AcceptOverlap then
                    Inc(iSearchBufPos, 1)
                  else
                    Inc(iSearchBufPos, SearchLen)
                end
                else
                  Inc(iSearchBufPos, 1);
             end;
             Inc(iReaded, AmtTransferred);
          end;
       finally
          FileClose(FileToSearch);
       end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par Aka Guymelef Voir le message
    Bonjour,

    alors comme ça brut de fonderie je dirais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var
      Buffer : array[0..2097151] of byte;//(petit fichier : 2Mo)
      F: TFileStream; ...
    Mais bon je suis sûr qu'il y a moyen d'encore mieux faire
    salut
    merci de votre dévouement à tous
    je viens de tester ton code et apres quelques corrections mineures, je trouve le bon résultat, mais en un temps encore assez long.
    Lorsque je programmais en vb2005, j'avais une fonction qui était très rapide qui permettait de chercher dans un tableau :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
        Public Function search_arr_in_arr_all_instances(ByVal arr1() As Byte, ByVal arr2() As Byte) As Integer()
            Dim resultz(0) As Integer
            Dim a As Integer
            Dim b As Integer
            Dim c As Integer
            Dim nb As Boolean
            Dim d As Integer = arr2.Length - 1
            c = arr1.Length - arr2.Length
            For a = 0 To c
                If arr1(a) = arr2(0) Then
                    nb = True
                    For b = 0 To d
                        If arr1(a + b) <> arr2(b) Then
                            nb = False
                            Exit For
                        End If
                    Next
                    If nb = True Then
                        resultz(resultz.GetUpperBound(0)) = a
                        ReDim Preserve resultz(resultz.GetUpperBound(0) + 1)
                    End If
                End If
            Next
            Return resultz
     
        End Function
    Je viens de voir que d'autres solutions me sont proposées, je vais les tester une par une.
    Merci encore de votre obligence, je vous tiens au courant ...
    @+
    greg38bj

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par banban54 Voir le message
    bonjour

    pourquoi chercher '4442405454543031' d'un coup ?
    => parcourir le tableau jusqu'à la première occurrence de '44', puis vérifier si l'octet suivant correspond à '42', ou au choix si la suite correspond à '42405454543031', si ce n'est pas bon on continue la recherche du '44' suivant....

    autre optimisation:
    au lieu de transformer le tableau de bytes en char (hexa) pour comparaison pourquoi ne pas faire l'inverse? cad transformer '4442405454543031' en une suite de bytes (8 conversions au lieu de 2 000 000 au pire en fin de tableau)

    la combinaison des 2 optimisations devrait donner un très bon gain de temps.
    à+
    salut
    La solution que tu proposes ressemble fort au code que j'avais en vb2005, je pense que ce sera la solution pour laquelle j'opterai si aucune autre ne me convient (temps d'execution). merci à toi pour tes idées .

  10. #10
    Membre averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    Par défaut
    Re

    Citation Envoyé par greg38bj Voir le message
    bonjour à tous
    Je cherche à accélérer un peu mon code qui est très lent
    Voici le code :
    @ ShaiLeTroll
    à première vue greg38bj demande une optimisation de son code,
    ensuite il ne cherche pas la chaine '4442405454543031' dans un fichier, mais (d'après ce que j'ai compris) '4442405454543031' est la représentation hexadécimale de la donnée recherchée.

    à+

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, greg38bj, ton code ne compile, et même il est faux, tu aurais pu mettre un produit fini pour les tests ...
    Désolé pour le bout de code incomplet
    Voici donc une partie de mon code actuel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    type
      TFrmTest = class(TForm)
        OpenDialogBin: TOpenDialog;
        Tv1: TTreeView;
        ...
        procedure ...
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
        Buffer : array[0..2097151] of byte;
        BufferDest : array[0..2097151] of byte;
        procedure DecodeNoeud(adresse:longword);
        procedure decodeLevel1;
        procedure Ouvrir;
    	procedure ...
      end;
    var
      FrmTest: TFrmTest;
    implementation
    {$R *.dfm}
    var BinSize:longword;
    var Fichier:string;
     
     
    procedure TFrmTest.Ouvrir;
    var F: TFileStream;
    begin
      if OpenDialogBin.Execute then
        begin
    	FillChar(buffer, SizeOf(buffer), 0);
    	F:=TFileStream.Create(OpenDialogBin.Filename,fmOpenRead);
    	F.Read(Buffer,F.Size);
    	BinSize:=F.Size;
    	F.Free;
    	fichier:= OpenDialogBin.Filename;
    	move(buffer,bufferdest,binsize);
    	decodeLevel1;
    	end;
    end;
     
    procedure TFrmTest.decodeLevel1;
    var PosA:longword;
        s,s1:string;
    begin
    tv1.Items.Clear;
    tv1.enabled:=false;
    //detection de l'adresse des adresses des items de niveau1
    PosA:=393344;
    s:='4442405453543031';
    While (PosA < (binsize-1)) or (s1=s)  do
    begin
    s1:=inttohex(ord(buffer[PosA]),2)+inttohex(ord(buffer[PosA+1]),2)+inttohex(ord(buffer[PosA+2]),2)+inttohex(ord(buffer[PosA+3]),2)+inttohex(ord(buffer[PosA+4]),2)+inttohex(ord(buffer[PosA+5]),2)+inttohex(ord(buffer[PosA+6]),2)+inttohex(ord(buffer[PosA+7]),2);
    if s1 = s then
    begin
    decodenoeud(PosA);
    end;
    PosA:=PosA+1;
    end;
    end;
    J'espère avoir réparé mon erreur, je vais donc tester maintenant la fonction SearchStringInBigFileLazy.
    @+
    greg

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut fonction SearchStringInBigFileLazy
    la fonction SearchStringInBigFileLazy ne me permettra pas d'obtenir l'offset ou les offset où la chaine recherchée sera trouvée; elle ne me donnera que le nombre d'occurrence de cette chaine dans le fichier.
    Merci quand même et super code quand même, je me le garde sous le coude .
    Peut être que je vais modifier ce code pour qu'il me donne les offset plutôt que les occurrences.
    @+
    greg38bj

  13. #13
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    SearchStringInBigFile, la grande soeur de SearchStringInBigFileLazy le fait ! voir le lien plus haut !
    Lazy ça aurait du te faire penser qu'il y avait une version moins flémarde ...

    C'est bien, on dirait que personne ne voit quand je mets un lien ... à chaque fois, je dois me répèter ...

    EDIT, tient, au passage, j'ai fait la fonction Array, trop facile, ... et en appelant plusieurs fois SearchByteArrayInByteArray en passant l'index récupéré à la précédente, tu peux récupérer l'ensemble des offsets ... en plus, ça dure 5 ms pour l'exemple fourni ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    function SearchByteArrayInByteArray(const SearchArray, SourceArray: array of Byte; StartIndex: Integer = 0): Integer;
    var
      IdxSearch, LenSearch, HighSearch: Integer;
      IdxSource, LenSource: Integer;
    begin
      LenSearch := Length(SearchArray);
      if (LenSearch > 0) then
      begin
        LenSource := Length(SourceArray);
        if (LenSource >= LenSearch) and (StartIndex < LenSource) then
        begin
          IdxSearch := 0;
          HighSearch := LenSearch - 1;
          for IdxSource := StartIndex to LenSource - 1 do
          begin
            if SourceArray[IdxSource] = SearchArray[IdxSearch] then
            begin
              if IdxSearch = HighSearch then
              begin
                Result := IdxSource - LenSearch + 1;
                Exit;
              end
              else
                Inc(IdxSearch);
            end
            else
              IdxSearch := 0;
          end;
        end;
      end;
     
      Result := -1;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    procedure TFrmTestMemory.BtnSearchArrayInArrayClick(Sender: TObject);
    var
     SearchArray, SourceArray: array of Byte;
     S: string;
     
     StartTick, EndTick, TickPerSec: Int64;
     TimeIteration: Cardinal;
     OK: Boolean;
    begin
      S := '4442405454543031';
     
      SetLength(SourceArray, 2097152);
      ZeroMemory(SourceArray, 2097152);
      CopyMemory(@SourceArray[2097152 - Length(S)], @S[1], Length(S)); // on met le tableau à la fin pour rigoler ...
     
      SetLength(SearchArray, Length(S));
      CopyMemory(@SearchArray[0], @S[1], Length(S));
     
       QueryPerformanceCounter(StartTick);
       try
          OK := SearchByteArrayInByteArray(SearchArray, SourceArray) = 2097152 - Length(S);
       finally
          QueryPerformanceCounter(EndTick);
          QueryPerformanceFrequency(TickPerSec);
          TimeIteration := Round((EndTick - StartTick) / TickPerSec * 1000);
       end;
       MemoTimes.Lines.Add('SearchByteArrayInByteArray : ' + IntToStr(TimeIteration) + ' ms');
       if OK then
         ShowMessage('OK')
       else
        ShowMessage('Raté !');
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 21
    Points : 10
    Points
    10
    Par défaut Merci
    merci ShaiLeTroll.
    Ton dernier code c'est de la balle au niveau rapidité, je ne désespère pas d'aller voir le lien d'ici ce soir.
    Vous êtes vraiment fort.
    Merci à tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Rechercher dans un array
    Par Z20500 dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 06/02/2014, 16h15
  2. Recherche dans Tableau/Array
    Par Danyel dans le forum VB.NET
    Réponses: 9
    Dernier message: 13/04/2008, 21h26
  3. Recherche dans un string array
    Par NicoNGRI dans le forum C#
    Réponses: 2
    Dernier message: 15/02/2007, 09h54
  4. [Tableaux] Problème PHP - Recherche dans un Array
    Par daniel_gre dans le forum Langage
    Réponses: 1
    Dernier message: 18/07/2006, 09h10
  5. [Tableaux] rechercher dans une variable array()
    Par tom06440 dans le forum Langage
    Réponses: 2
    Dernier message: 29/03/2006, 17h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo