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

Langage Delphi Discussion :

Problème de passage de paramètres


Sujet :

Langage Delphi

  1. #1
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut Problème de passage de paramètres
    Bonjour,

    Pour trier le fichier de lignes de texte formatté du type suivant sur la base de comparaisons effectuées sur une profondeur de tri comprise entre les caractères d'indice icar1 et icar2 c'est à dire correspondant soit à une date un libellé ou un code postal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Zqkjlk    Mlsldfskd 2004/11/21 kùakùkaka z1 69006 Lyon 
    Bqmslkdu  Kdmlq     2001/06/02 dqmlkjsdl d2 83600 Fréjus
    Qfdl      Lkdfmslk  2005/03/15 vdlsmlk   s9 33000 Bordeaux
    Cinzm     Uskjd     1992/04/22 kdjqlk    q2 01000 Bourg
    Asmlkfdjm Zkfjmsj   2003/05/14 roizjero  r5 67008 Strasbourg
    Zics      Ddqkjmlk  2001/06/02 seriz     r8 67001 Strasbourg
    Bicqmd    Fmlksje   1995/01/06 ffjczcjz  p7 74008 Annecy
    Nqkj      Isldfskd  2007/11/28 kùakùk    k7 04523 Trifoully
    Charpi    Allqk     2003/02/25 pzkeorea  a0 45123 Orléans
    Mslkd     Bfmlksfd  1955/07/14 mlsk      m9 06012 Nice
    Ziuyefco  Aeuycx    1984/04/08 aqlskjd   b9 42561 Firminy
    ... j'ai voulu simplifier en utilisant le code suivant :
    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
    procedure Trier( List: TStringList; Index1, Index2, icar1,icar2 : Integer);
    var       ic1, ic2 : integer;
    
              function  fCompareZ1(List: TStringList; Index1, Index2: Integer): Integer;
              var       v1, v2: string;
              begin     v1 := List[Index1];
                        v1 := Copy(v1,ic1,ic2-ic1+1); <- ne marche pas : ic1 et ic2 prennent ici des valeurs aberrantes
                        //v1 := Copy(v1,11,20-11+1); <- marche mais est est sans intérêt 
                        v2 := List[Index2];
                        v2 := Copy(v2,ic1,ic2-ic1+1); <- ne marche pas : ic1 et ic2 prennent ici des valeurs aberrantes
                        //v2 := Copy(v2,11,20-11+1); <- marche mais est est sans intérêt 
                        showMessage(v1+' '+v2);
                        if v1 < v2 then result := -1
                        else if v1 > v2 then result := 1 else result := 0;
              end;
    
    begin     ic1:=icar1; ic2:=icar2; 
              List.CustomSort(@fCompareZ1);
    end;
    ... malgré le recours aux variables-relais locales ic1 et ic2 celles-ci ne sont pas prises en compte correctement par la fonction fCompareZ1 encapsulée.
    ... Alors qu'avec le code d'essai suivant les paramètres icar1 et icar2 passent directement (sans avoir à utiliser les variables-relais locales ic1 et ic2) et sont correctement pris en compte par la fonction fCompareZ2 encapsulée :
    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
    procedure Essai( List: TStringList; Index1, Index2, icar1,icar2 : Integer);
    var       j : integer;
    
              function  fCompareZ2(List: TStringList; Index1, Index2: Integer): Integer;
              var       v1, v2: string;
              begin     v1 := List[Index1];
                        v1 := Copy(v1,icar1,icar2-icar1+1); //<- ok marche
                        v2 := List[Index2];
                        v2 := Copy(v2,icar1,icar2-icar1+1); //<- ok marche
                        showMessage(v1+' / '+v2); //<- ok marche
                        if v1 < v2 then result := -1
                        else if v1 > v2 then result := 1 else result := 0;
              end;
    
    begin     for j:=0 to List.Count-2 do fCompareZ2(List,Index1, j);
    end;
    ... ce deuxième code n'a bien sûr comme seul intérêt que de montrer que dans ce 2ème cas les paramètres passent.

    ... Mais comment, svp, faire passer et accepter ces paramètres dans le code de tri ???

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  2. #2
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut

    Premièrement je ne définirais pas fonction 'callback' fCompareZ1 comme une fonction imbriquée.
    Je la définirais comme fonction à part entière et hors classe.

    Quant ic1 et ic2: utilise des variables publiques ou globales (je ne sais jamais le terme exact).

    @+ Claudius

  3. #3
    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
    Je serais du même avis que Claudius, ... les variables globales, mais tu n'es pas obligé de les déclarer au début de l'unité, tu peux très bien, mettre comme ceci :

    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
     
    procedure TBidule.Machin();
    begin
      ...
    end;
     
    var
      ic1, ic2
     
    function  fCompareZ1(List: TStringList; Index1, Index2: Integer): Integer;
    begin
      ..
    end;
     
    procedure Trier( List: TStringList; Index1, Index2, icar1,icar2 : Integer);
    begin
      ic1 := icar1;
      ic2 := icar2;
     
      List.CustomSort(@fCompareZ1);
    end;



    Sinon, il est vrai que utiliser une sous-fonction pour CustomSort c'est assez osé, je n'aurais pas cru qu'il compile !

    Je pense qu'il y a un problème de mémoire, si tu utilise des variables de la fonction-mère dans la fonction-fille via CustomSort, il est fort possible que l'adresse de ic1 et ic2 sont calculés en fonction de l'adresse de la méthode appelante (un truc dans un registre ou sur la pile), donc si tu l'appelles d'ailleurs, cela ne peut pas fonctionner ...
    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

  4. #4
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Salut
    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, il est vrai que utiliser une sous-fonction pour CustomSort c'est assez osé, je n'aurais pas cru qu'il compile !
    J'ai fais le test, ça compile mais j'ai une belle AV à l'exécution.

    @+

  5. #5
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-Bonjour,

    Merci Cl@udius et ShaiLeTroll pour vos explications : cela m'intriguait. Je vais suivre vos conseils et tester illico.

    A+

    EDIT : Re-merci : testé ça marche : résolu.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  6. #6
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Effectivement ce code ne passe pas
    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
    procedure Trier(List: TStringList; Index1, Index2, icar1, icar2: Integer);
    var
      ic1, ic2: Integer;
     
      function fCompareZ1(List: TStringList;
        Index1, Index2: Integer): Integer;
      var
        v1, v2: string;
      begin
        v1 := List[Index1];
        v1 := Copy(v1, ic1, ic2-ic1+1);
        v2 := List[Index2];
        v2 := Copy(v2, ic1, ic2-ic1+1);
        ShowMessage(v1+' '+v2);
        if v1 < v2 then
          Result := -1
        else if v1 > v2 then
          Result := 1
        else
          Result := 0;
      end;
     
    begin
      ic1 := icar1;
      ic2 := icar2;
      List.CustomSort(@fCompareZ1);
    end;
    Et pourtant j'aurais cru que ça fonctionnait...

    Cela dit, les variables globales, c'est pas top question propreté. Et avec des threads ça serait même dangereux.

    Je propose une solution à ce type de problèmes avec la construction de routine pointant sur une méthode. Le code complet fait partie de la SCL. Tu peux l'utiliser comme ça :
    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
    uses
      ScDelphiLanguage;
     
    type
      PIC = ^TIC;
      TIC = record
        ic1, ic2: Integer;
      end;
     
    function fCompareZ1(IC: PIC; List: TStringList;
      Index1, Index2: Integer): Integer;
    var
      v1, v2: string;
    begin
      v1 := List[Index1];
      v1 := Copy(v1, IC.ic1, IC.ic2-IC.ic1+1);
      v2 := List[Index2];
      v2 := Copy(v2, IC.ic1, IC.ic2-IC.ic1+1);
      ShowMessage(v1+' '+v2);
      if v1 < v2 then
        Result := -1
      else if v1 > v2 then
        Result := 1
      else
        Result := 0;
    end;
     
    procedure Trier(List: TStringList; Index1, Index2, icar1, icar2: Integer);
    var
      IC: TIC;
      Proc: TStringListSortCompare;
    begin
      IC.ic1 := icar1;
      IC.ic2 := icar2;
      @Proc := MakeProcOfRegisterMethod(MakeMethod(@fCompareZ1, @IC), 3);
      try
        List.CustomSort(Proc);
      finally
        FreeProcOfMethod(@Proc);
      end;
    end;
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    A Sjrd : C'est sympa d'avoir proposé une autre solution malgré le tag "Résolu". J'ai récupéré ton code pour le cas où j'aurai un besoin similaire : Merci.

    Par contre pour l'instant j'ai abandonné le tri avec SL.CustomSort() car un test comparatif sur un fichier de 200 000 lignes formattées d'une centaine de caractères chacune triées entre les colonnes 11 à 20 j'ai eu les résultats suivants :
    - tri avec SL.CustomSort : 4943 ms
    - tri avec AlphaSort : 250 ms soit 19,7 fois plus rapide
    ... j'aurais préféré l'inverse car avec SL.CustomSort on aurait réglé le problème avec très peu de lignes de code.

    ... j'en profite pour dire que je suis surpris qu'on parle surtout du QuickSort et rarement de AlphaSort lorsqu'il est question de tri de chaînes.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  8. #8
    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
    Effectivement, un de mes anciens collègues, a écrit un article de pascalissime entre AlphaSort et QuickSort ... faut dire qu'il était ultra-calé sur le travail des chaines, c'est avec lui que j'ai compris le Hashage
    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

  9. #9
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    A ShaiLeTroll : J'avais découvert AlphaSort en fouinant dans des sites universitaires, mais ayant récupéré uniquement le code à l'époque, quand j'ai voulu m'y remettre récemment j'ai essayé de piger son fonctionnement et c'est là que je n'ai plus retouvé ce site mais je suis tombé sur celui de Delafosse qui correspond à l'article que tu cites et qui m'a éclairé un peu mieux ma lanterne. J'ai pas encore entièrement pigé mais ça a été suffisant pour me permettre de le modifier de sorte que l'on puisse l'utiliser pour faire du tri sur des lignes de texte formatté sur une profondeur de tri allant de l'indice Icar1 à Icar2.

    ... A propos de Pascalissime : Dommage qu'il ne soit plus publié.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

Discussions similaires

  1. Réponses: 19
    Dernier message: 09/06/2006, 10h03
  2. Problème de passage de paramètres à une procedure
    Par momo62 dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 22/12/2005, 15h22
  3. [template] problème de passage de paramètres
    Par vinny_the_true dans le forum C++
    Réponses: 2
    Dernier message: 14/12/2005, 01h15
  4. Réponses: 9
    Dernier message: 13/05/2005, 03h13
  5. problème de passage de paramêtre sous mozilla
    Par mat10000 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 27/09/2004, 10h48

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