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 Pascal Discussion :

[LG]Problème avec if/else.


Sujet :

Langage Pascal

  1. #1
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut [LG]Problème avec if/else.
    bonjour, j'ai une fonction comme suit :
    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
    function Compare(t,s : string) : boolean;
    var a : boolean;
        i : integer;
    begin
    a := TRUE;
    i:=0;
    while (i<>length(s)) and a do
          begin
          inc(i);
          if (s[i]>='a') and (s[i]<='z') then
             begin
             if (ord(t[i])=ord(s[i])) or (ord(t[i])=ord(s[i])-32) then a:=TRUE
             else a:=FALSE;
             end;
          if (s[i]>='A') and (s[i]<='Z') then
             begin
             if (ord(t[i])=ord(s[i])) or (ord(t[i])=ord(s[i])+32) then a:=TRUE
             else a:=FALSE;
             end
          else
              begin
              if (t[i]=s[i]) then a:=TRUE
              else a:=FALSE;
              end;
          end;
    Compare:=a;
    end;
    Le problème, c'est qu'elle ne fonctionne pas correctement.

    En fait, elle devrait regarder si deux mots (s et t) sont équivalents, à des majuscules près, mais ça ne marche que dans le cas où le mot "s" est entièrement en majuscule.

    J'ai trouvé que c'était dû au "else" car, si je l'enlève et que je regarde deux mots entièrement formés de lettres ('a'..'z' ou 'A'..'Z'), il fonctionne correctement.

    Ce qu'il y a c'est que je ne comprends pas pourquoi ça fait ça ! Donc si vous pouviez m'expliquer, ce serait sympa.
    Si de plus vous pouviez me dire comment y remédier de façon "élegante", ce serait encore mieux. (en fait je vois bien une solution qui consisterait à ramener la fonction "principale" à un simple if/else, mais c'est loin d'être élégant : ça donnerait un truc du genre) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if ( (s[i]>='a') and (s[i]<='z') ) or ( (s[i]>='A') and (s[i]<='Z') ) then
       begin 
       if  (s[i]>='a') and (s[i]<='z') then
          begin
          if (ord(t[i])=ord(s[i])) or (ord(t[i])=ord(s[i])-32) then ... 
          else ...;
          end
       else if  (s[i]>='A') and (s[i]<='Z') then
          begin
          if (ord(t[i])=ord(s[i])) or (ord(t[i])=ord(s[i])+32)) then ...
          else ...;
          end;
       end
    else begin ... end;
    Donc si vous voyez comment faire, tout en conservant une forme proche de ma première fonction, je préfèrerais !

  2. #2
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Lorsque tu dois tester plusieurs valeurs possibles pour une seule variable, tu peux utiliser un case plutôt qu'un if :

    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
     
    function Compare(t,s : string) : boolean;
    var a : boolean;
        i : integer;
    begin
    a := TRUE;
    i:=0;
    while ((i<>length(s)) and (a)) do
          begin
          inc(i);
          case ord(s[i]) of
          ord('a')..ord('z') : begin
                            if (ord(t[i])=ord(s[i])) or (ord(t[i])=ord(s[i])-32) then  a:=TRUE
             else a:=FALSE;
             end;
          ord('a')..ord('z') : begin
             if (ord(t[i])=ord(s[i])) or (ord(t[i])=ord(s[i])+32) then a:=TRUE
             else a:=FALSE;
             end;
          else 
              begin
              if (t[i]=s[i]) then a:=TRUE
              else a:=FALSE;
              end;
          end;
    Compare:=a;
    end;
    Ensuite puisque tu ne veux pas te préoccuper de la casse tu peux éviter de différencier majuscules et minuscules lors du test, en mettant tous les caractères alphabétiques en majuscules, avec la fonction upcase.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    function Compare(t,s : string) : boolean;
    var a : boolean;
        i : integer;
    begin
    a := TRUE;
    i:=1;
    while ((i<=length(s)) and (a)) do
        begin
        if Upcase(t[i])=Upcase(s[i]) then a := true else a := false;
        inc(i);
        end;
    Compare:=a;
    end;
    Upcase met en majuscule un caractère alphabétique, mais ne change pas les autres caractères (chiffres et ponctuation), donc tu peux comparer sans différencier majuscules et minuscules...

    a+
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  3. #3
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut
    Merci bien wormful, elle m'a l'air bien sympathique cette fonction Upcase !

    Heureusement (pour moi) que tu as répondu vite parce que je venais de (re)trouver la solution et j'aurais probablement effacé ce post.

    j'aurais tout simplement pu écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if (s[i] >= 'a' , ...
    else if (s[i]>='A', ...
    else ...
    J'avoue que sur le coup je n'y ai pas pensé.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Points : 711
    Points
    711
    Par défaut
    salut,

    attention, il faut aussi vérifier que les longueurs des chaines sont compatibles:
    si length(t) < length(s) ==> plantage si variable i > length(t) tout en étant <= length(s)

    (et de toute manière, 2 chaines ne peuvent être égales si elles ont des longueurs différentes)

    de plus, la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        if Upcase(t[i])=Upcase(s[i]) then a := true else a := false;
    peut être remplacée par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        if Upcase(t[i]) <> Upcase(s[i]) then a := false;
    car a vaut déjà True, et on sort de la boucle dés qu'une comparaison est fausse.

    ça devient donc:
    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
     
    function Compare(t,s : string) : boolean;
    var 
      a : boolean;
      i : integer;
    begin
      a := (Length(s) = Length(t)) ; { a = true si s et t ont même longueur }
      if a then
      begin
        i:=1;
        while ((i<=length(s)) and (a)) do
        begin
          if Upcase(t[i]) <> Upcase(s[i]) then a := false;
          inc(i);
        end;
      end;
      Compare:=a;
    end;
    Compilation sans erreur ne signifie pas programme sans erreur.
    L'indentation n'a pas été imaginée pour faire beau, mais pour faciliter la lecture des programmes.

  5. #5
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Si on veut vraiment optimiser :

    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
     
    function Compare(T, S: String): Boolean;
    var A: Boolean;
        I: Integer;
    begin
      A := (Length(S) = Length(T));
      I := 1;
      while ((A) and (I <= Length(S))) do
      begin
        A := Upcase(T[I]) <> Upcase(S[I]);
        I := I +1;
      end;
      end;
      Compare := A;
    end;
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Points : 711
    Points
    711
    Par défaut
    @ wormful_sickfoot:
    oui, le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if a then
    begin
      ...
    end;
    n'est pas nécessaire, mais je l'ai mis car je trouve que ça rend le code plus compréhensible pour un(e) débutant(e), ce qui manifestement est le cas de Loceka
    Compilation sans erreur ne signifie pas programme sans erreur.
    L'indentation n'a pas été imaginée pour faire beau, mais pour faciliter la lecture des programmes.

  7. #7
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Citation Envoyé par thewho
    ça rend le code plus compréhensible pour un(e) débutant(e)
    Entièrement d'accord avec toi
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  8. #8
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    2 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 2 276
    Points : 4 845
    Points
    4 845
    Par défaut
    Merci bien de cette attention. :o

    A vrai dire je suis encore plus distrait que je ne suis débutant, mais je comprend bien qu'un "while a do" ne nécessite pas un "if a then while a do"...

    Par contre j'ai encore beaucoup à apprendre en ce qui concerne l'optimisation !

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

Discussions similaires

  1. problème avec la "ELSE"
    Par amazircool dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 17/12/2007, 14h23
  2. [Makefile] : Difficulte avec if/else
    Par samiblide dans le forum Systèmes de compilation
    Réponses: 2
    Dernier message: 20/09/2007, 22h33
  3. problème avec if..else..endif
    Par casavba dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 01/08/2007, 11h14
  4. Probleme avec un "ELSE"
    Par jam92400 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 21/02/2007, 09h36
  5. Problèmes avec des else if
    Par Kr00pS dans le forum C
    Réponses: 2
    Dernier message: 15/04/2006, 11h04

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