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

Turbo Pascal Discussion :

[TPW] Problème de chaînes


Sujet :

Turbo Pascal

  1. #1
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 11
    Par défaut [TPW] Problème de chaînes
    J'ai toujours un problème avec les traitement de chaines (niveau débutant, prière s'arme de patience )
    Donc, il s'agit d'écrire un programme qui lit une 'phrase' sous forme de chaîne de caractères et l'inverse:
    entrée: le monde est petit
    sortie: petit est monde le
    sachant que deux 'mots' sont séparés par un seul espace, et que la chaine ne doit pas commencer ni finir par un espace
    Mon (pseudo:p) prg est constitué de trois parties controle et modification de l'entrée selon les critère ci-dessus, comptage du nb de 'mots' contenus, ensuite, ben, le traitment qui inverse la chaine en utilisant le nb de mots..
    Alors voilà:
    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
     
    program aaa;
    uses wincrt; (* euh, oui j'utilise TPW :p *)
     
    var
    i,j,c,  (*compteurs*)   
    l, (*longuer de notre chaine*)
    nb,  (* nb d'esapces*)
    nbm,  (*nb de mots =nb d'espace +1*)
    p,  (*pos du 1er espace*)
    x  (*longuer du 1er mot *)   : integer;
     
    ch,espace,res,m : string;
    esp: boolean ; (*s'il existent deux espaces qui se suivent ou non *)
     
     
     
    begin
    write('entrer votre chaine')     ;
    read(ch);
    l:=length(ch);
     
     
    for j:= 1 to l do
    if (ch[j]=' ') and (ch[j-1]=' ') then
     
    delete(ch,j,1);   
     
      (* autre possiblité, qui ne fonctionne pas non plus apparemment:
    j:=0;esp:=false;
    repeat
    j:=j+1;
    if (ch[j]=espace) and (ch[j-1]=espace) then
    begin esp:=true;
    delete(ch,j,1);
    end;
    until (esp=false) or (j=l) ;       *)
     
     
     
     
    if ch[1]=' ' then delete(ch,1,1);
    if ch[l]=' ' then delete(ch,l,1)  ;
     
     
     i:=0; nb:=0;
    repeat
    i:=i+1;
    if ch[i]=' ' then nb:=nb+1;
    until (i=length(ch)-1);
     
    writeln(nb,'espaces');  (* juste pour voir :p *)
    nbm:=nb+1;
    writeln(nbm, 'mots');
     
    res:=''; (*chaine vide qui contiendra la nvlle chaine inversée *)
     
    for c:=1 to nbm do
     
    espace:=' ';
    p:=pos(espace,ch);   (* position du 1er espace, précédé donc du 1er mot*)
    m:=copy(ch,1,p);     (* exrait le 1er mot dans 'm' *)
    x:=length(m);
    delete(ch,1,x);      (* supprime le 1er mot*)
    res:=m+res;
     
    writeln('chaine inversée',res)
     
    end.
    Merci

  2. #2
    Membre très actif
    Avatar de diden138
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    714
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 714
    Par défaut salut,
    t'a beacoup d'erreur vulgaire comme le dit hdd34( le moderateur) ch[j]=esp;type incompatible!!! 2eme chose delet(ch,1,1) jamais vu utilise plutot delet(ch[j])sinon la première methode fera l'affaire je trouve
    sinon a part ca je trouve ton programme clean.

  3. #3
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 11
    Par défaut
    ch[j]=esp;type incompatible!!!
    ah oui je voulais dire: espace pas esp

    sinon la première methode fera l'affaire je trouve
    mais non ça ne marche pas

  4. #4
    Membre très actif
    Avatar de diden138
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    714
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 714
    Par défaut resalut,
    est ce que tu est sur que delet (ch[j],j,1)existe parceque moi j'vais l'habitude de travailler avec delet(ch[j]);

  5. #5
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 11
    Par défaut
    euh.. normalement oui:

    delete(ch,p,n) : efface n caractères de ch à partir de la position p

  6. #6
    Membre très actif
    Avatar de diden138
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    714
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 714
    Par défaut resalut,
    oui t'a raison ecoute je vais reflechir a ton prob demain je te donnerai une reponseok bon fin de soirée

  7. #7
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 11
    Par défaut
    Merci

  8. #8
    Membre émérite Avatar de Sheriff
    Inscrit en
    Octobre 2004
    Messages
    608
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 608
    Par défaut
    Salut ! si je peux me permettre, je trouve que tu utilises beaucoup trop de variables et donc de code dans ton programme ; je t'explique mon principe :

    - tu as une chaine qui contient la phrase en question
    - tu as une autre chaine de même longueur qui contient la phrase inversée;
    - tu parcours la chaine a partir de la fin, biensur avec une variable entiere i que tu initialise avec la longueur de la phrase.
    lorsque chaine1[i]=' ' (l'espace) tu recopie chaque caractère jusqu'au prochain espace dans ta deuxième chaine en concaténant à chaque fois(au besoin tu peux utiliser le break pour sortir de l'itération lorsque tu tombe sur un espace)
    enfin il ne te reste plus qu'à afficher la seconde chaine et t'as la phrase inversée.

    au prochain message je t'envoie une portion de code, si tu veux bien
    a+

  9. #9
    Membre très actif
    Avatar de diden138
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    714
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 714
    Par défaut salut,
    A mon avis ce code fera l'affaire tu peux biensur l'ameliorer j'ai pas eu beaucoup de temp pour ca
    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
    {j'ai relaiser ce programme celon l'exemple que tu nous a donner hello world devient world hello}
    program inverse;
    uses crt;
    var
    ch,ch1:string[80];
    l,i,j,k,pos:integer;
    p:char;
    begin
    clrscr;
    write('Entrer la chaine de caractere:'); {Il appuye sur tab puis entre ta phrase }
    p:='!';
    read(ch);
    l:=length(ch); k:=length(ch); {j'ai voulu faire simple arceque j'ai pas le temp si tu veuc tu peuc ameliorer ton code facilement}
    for i:=1 to l do
    begin
    if ch[i]=' ' then ch[i]:=p;
    end;
    for i:=l downto 1 do
    begin
    if ch[i]='!' then
    begin
    ch[i]:=' ';
    pos:=i;
    for j:=pos to k do
    begin
    ch1[j]:=ch[j];
    write(ch1[j]);
    k:=k-(k-i);
    end;
    end;
    end;
    readln;
    readln;
    end.

  10. #10
    Membre Expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Par défaut
    Le code juste au-dessus n'a manifestement pas été testé et ne fonctionne pas...


    Sinon voilà un algorithme pour effectuer ça... A analyser et comprendre :

    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
    function ReverseWords(const S: string): string;
    const
      Spaces = [' ', #9]; { Espace et tabulation }
    var
      Result: string;
      Len: Integer;
      i: Integer;
      B: Integer;
    begin
      Result := '';
      Len := Length(S);
      B := 1;
    
      { Suppression des espaces de début et de fin }
      while S[b] in Spaces do Inc(B);
      while S[Len] in Spaces do Dec(Len);
      
      { On ajoute tous les mots sauf le dernier }
      i := B;
      while i <= Len do
      begin
        { L'espace permet de délimiter la fin d'un mot }
        if (S[i] in Spaces) or (i = Len) then
        begin
          { Il faut se placer derrière le dernier mot }
          if (i = Len) then Inc(i);
          { On ajoute le mot }
          Result := Copy(S, B, i - B) + ' ' + Result;
          { On saute les espaces qui se suivent }
          while (i < Len) and (S[i + 1] in Spaces) do Inc(i);
          { On indique le début du prochain mot }
          B := i + 1;
        end;
    
        { On passe au caractère suivant }
        Inc(i);
      end;
      
      { On enlève l'espace en trop qui s'est glissé }
      Delete(Result, Length(Result), 1);
    
      ReverseWords := Result;
    end;

  11. #11
    Membre habitué
    Inscrit en
    Août 2005
    Messages
    11
    Détails du profil
    Informations forums :
    Inscription : Août 2005
    Messages : 11
    Par défaut
    merci à tous pour votre aide

    quant au controle de la chaine, je l'ai corrigé, voilà:


    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 control(var ch:string);
    var
      esp:boolean;
      i:integer;
    writeln('entrer chaine');readln(ch);
    esp:=false;
     
    repeat
     
       for i:=1 to length(ch) do
       if (ch[i]=' ') and (ch[i+1]=' ') 
       then begin esp:=true; delete(ch,i,1);
       end;
    until (esp=false) or (i=length(ch));
    Je risque de poster d'autres sujets de ce genre, j'ai un exam bientot, et plus de prof pour poser mes questions

  12. #12
    Membre Expert
    Avatar de Eric Sigoillot
    Inscrit en
    Mars 2002
    Messages
    1 212
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 212
    Par défaut
    Bonjour,

    Ton code est dangereux et source de failles : quand i = Length(ch), ch[i+1] n'est pas défini.

    De plus, tu fais une boucle allant de 1 à Length(ch), mais dans le corps de la boucle, tu fais des appels à Delete(ch). Donc la longueur de la chaîne diminue. Tu supposes que la condition de la boucle for est réévaluée à chaque itération. Ce n'est pas forcément le cas en Pascal.

    En effet, la norme indique ceci :
    Apart from the restrictions imposed by these requirements, the for-statement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for v := e1 to e2 do body
    shall be equivalent to
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    begin
      temp1 := e1;
      temp2 := e2;
      if temp1 <= temp2 then
      begin
        v := temp1;
        body;
        while v <> temp2 do
        begin
          v := succ(v);
          body
        end;
      end;
    end;
    Comme tu peux le voir, la condition de sortie (e2) est évaluée en début de boucle, et elle n'est jamais réévaluée en cours de boucle. La condition finale est une pseudo-constante pour la boucle.

    @++

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

Discussions similaires

  1. [TPW]J'ai besoin de WINCRT
    Par luno2545 dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 18/01/2004, 22h00
  2. tpw turbo pascal for windows
    Par tripper.dim dans le forum Turbo Pascal
    Réponses: 3
    Dernier message: 29/11/2003, 23h06
  3. [TPW]EnumWindowsProc
    Par Sub0 dans le forum Turbo Pascal
    Réponses: 2
    Dernier message: 19/08/2003, 20h57
  4. [TPW][cours]Demande d'aide pour finir un programme
    Par jf dans le forum Turbo Pascal
    Réponses: 21
    Dernier message: 16/06/2003, 18h10
  5. ListView->Items->Clear() !!! Qques probl de perf
    Par Nicolas_a69 dans le forum C++Builder
    Réponses: 3
    Dernier message: 30/08/2002, 11h49

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