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

Free Pascal Discussion :

Suppression des espaces dans une chaîne


Sujet :

Free Pascal

  1. #1
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut Suppression des espaces dans une chaîne
    Bonjour,

    j'essaye de réaliser un programme qui, en lisant une chaîne, renvoie la même chaîne mais sans espace ( chaîne de caractères ). J'ai déjà réalisé mon programme mais il y a encore quelques réglages à faire. Tout d'abord, je préfère vous montrer mon algo et avoir votre avis :
    • 1. Je lis la chaîne avec une boucle ;
    • 2. Si le caractère rencontré est un espace :
      • 3. Alors on remplace cet espace par le caractère suivant.
    • 4. On renvoie la nouvelle chaîne.

    Est-ce que c'est honorable comme algorithme ? Dites-moi juste s'il est valable ; si vous en avez un de mieux, c'est pas grave je garderai le mien car sinon je ne bosse plus .

    Merci

  2. #2
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Bonjour, pourquoi veux-tu utiliser une boucle pour lire la chaine?

    Si tu veux lire une chaine entrée au clavier il suffit de faire un readln "classique", qui mettra toute la phrase dans la variable.
    Développeur écolo, je suis pour le développement durable.

  3. #3
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    là je parlais de l'algo de la fonction et non du programme principal...

  4. #4
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    dans mon programme principal j'ai effectivement utilisé un red , mais dans la fonction une boucle .

  5. #5
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Ok je comprends.

    Juste une remarque, si tu remplaces par le caractère suivant tu vas à nouveau tomber sur un espace au prochain tour de boucle, et ainsi de suite.
    Donc, au càs où ce n'est pas déjà ce que tu voulais faire, il vaut mieux avancer tous les caractères suivants d'une case.
    Développeur écolo, je suis pour le développement durable.

  6. #6
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    une autre petite question avant de montrer mon code , est ce que le paramètre que j'ai passé en entrée peut être le résultat que renvoit ma fonction ?

  7. #7
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Si tu as modifié ce paramètre dans le corps de la fonction et que le paramètre n'est pas déclaré comme constant, ça devrait aller.
    Mais le meilleur moyen d'en être sur c'est d'essayer !
    Développeur écolo, je suis pour le développement durable.

  8. #8
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    alors voici le code de mon programme pinrcipal ( le truc le plus facile à faire et il est bon çà pas de doute ) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
     
    u: STRING;
     
    begin
     
    read(u);
    writeln(reply(u));
     
    end.
    et voici le code de ma fonction mais elle ne marche pas car je pense que j'ai du mal traduire le fait de remplacer les espaces par le caractè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
    function reply(s: STRING): STRING; //ma fonction retourne bien une chaine et manipule une chaine , donc jai mis une chaine en entrée et en sortie
    var
     
    i: CARDINAL; //variable pour la boucle for
    w: char; //variable pour définir un espace
     
    begin
     
       w := ' '; //affectation de la valeur à la variable
     
     
    for i := 1 to length(s) do //parcours de la chaine
    begin
    if s[i] = w then //condition de changement
    w := w + s[i]; //je crois que le problème est ici , je crois que cette ligne veut dire de remplacer l'espace par le caractère d'après mais je ne suis pas certaine .
    end;
    reply := s;
    end;

  9. #9
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    L'erreur c'est que quand tu fais ça:
    Tu tentes de concatener 2 caractères et de mettre le resultat dans w.
    Comme w est de type char le compilateur t'indique une erreur de type incompatible. C'est normal puisqu'une variable de type caractère ne peut contenir qu'un seul caractère (logique !).

    De toutes façons, même si ça marchait, ça ne ferait pas ce que tu veux.

    Ca changerait la valeur de w, pas la chaine.

    Ce que tu dois faire c'est quelque chose comme: Ce qui aurait pour effet de remplacer le caractere courant dans la boucle par le caractère suivant de la chaine.
    Mais ça ne suffit pas car si tu as la chaines: 'bonjour monsieur', le resultat serait 'bonjourmmonsieur'.
    Tu dois donc avancer d'une "case" toutes les lettres qui suivent le caractère d'espace et pour ça c'est une bonne idée d'utiliser une 2e boucle for.
    Développeur écolo, je suis pour le développement durable.

  10. #10
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    Mais ça ne suffit pas car si tu as la chaines: 'bonjour monsieur', le resultat serait 'bonjourmmonsieur'.
    c'est exactement çà que je veux faire

  11. #11
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    ah non j'ai vu la nuance t'as écrit 2 fois m ok , bon faut que je réfléchisse quelques minutes .

  12. #12
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    j'ai beau réfléchir je vois pas , j'ai fait quelques essais non concluants...

  13. #13
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Visualise la chaine complete comme une suite de case contenant chacune un caractere.

    Ca donne un truc dans ce genre:

    |b|o|n|j|o|u|r|

    en réalité c'est plutôt ça: |r|b|o|n|j|o|u|r|, mais ça n'a pas d'importance ici.

    Maintenant si ta chaine est "bon jour": |b|o|n| |j|o|u|r|, si tu veux supprimer l'espace, tu dois avancer toutes les lettres d'une case.

    Pour faire ça tu peux utiliser une boucle for, qui commence au caractere courant et qui termine a la fin de la chaine. A chaque tour de boucle elle remplace le caractere courant par le suivant.
    Ce qui donne ça en pascal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for i := 1 to length(s) do
      if s[i] = w then
        for j:= i to length(s) do // à partir de cette case
          s[j] := s[j+1]; // copier dans la case la lettre qui se trouve dans la case suivante
    Mais ça va poser un probleme car au moment où la boucle atteindra la derniere case, elle va essayer de lire un caractere dans la case suivante, qui n'existe pas !
    Là ce qui va se passer dépend du compilateur: soit ça va donner une erreur de compilation, soit ca va mettre quelque chose au hasard dans la derniere case ( en réalité elle contiendra ce qui se trouve à l'emplacement mémoire situé juste apres l'emplacement memoire de la derniere case).
    Donc il faut arreter la boucle une case avant la fin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for i := 1 to length(s) do
      if s[i] = w then
        for j:= i to length(s)-1 do 
          s[j] := s[j+1];
    Il ne faut pas oublier de rajouter j dans les déclarations de variables.
    Et il faut aussi penser que le derniere caractere de la chaine va etre recopié autant de fois qu'il y a d'espace dans la chaine.

    'bon jour' donnera 'bonjourr' donc il faut aussi prevoir de modifier la longueur de la chaine apres modification.
    Pour ca tu peux ajouter un compteur qui comptera le nombre d'espace rencontré, et diminuer la taille de la chaine d'autant de caractere qu'il y avait d'espaces.
    Développeur écolo, je suis pour le développement durable.

  14. #14
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    çà me parait super compliqué pour un exercice de débutant , 4 variables , je peux pas le croire on arrive à un programme de 50 lignes , on va plus s'y retrouver là mon algo de départ n'est déjà plus valable , t'es certain que ya pas plus court ?

  15. #15
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Ce n'est pas si long que ça.

    Tu peux déjà supprimer la variable w est comparé directement au caractere espace dans la boucle:

    Moi j'ai écris la fonction avec 3 variables, et 10 lignes de code, dont 2 sont un begin et un end.
    Développeur écolo, je suis pour le développement durable.

  16. #16
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    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 reply(s: STRING): STRING;
    var
     
       i: CARDINAL;
       j: CARDINAL;
     
    begin
     
    for i := 1 to length(s) do
    begin
    if s[i] = ' ' then
       for j := i to length(s) do
          s[j] := s[j+1];
          for i := 1 to length(s) do
             if s[i] = ' ' then
                for j := i to length(s)-1 do
                   s[j] := s[j+1];
    end;
    elle compile pas car j'ai eu bcp de mal avec tous ces for , je suis complètement découragée là j'ai limite envie d'arrêter la prog , toutes ces boucles juste pour supprimer des espaces , c'est franchement...

  17. #17
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Tu n'as pas besoin de toutes ces boucles, 2 suffisent.

    voici l'algo: (je met les balises code pour garder l'indentation)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    compteur vaut 0;
    pour i allant de 1 à la longueur de la chaine 
      si le caractere courant est un espace
        pour j allant du caractere courant jusqu a a la fin -1 
          le caractere courant prend le caractere suivant
          compteur augmente de 1
    la longueur de la chaine devient longueur de la chaine - compteur
    Ne t'en fais pas, il y a toujours des moments où on se décourage en programmation, que ce soit pendant l'apprentissage ou pendant le développement d'un projet. Mais tout comme dans la vie, une fois ce moment passé et le problème résolu on est reparti encore plus motivé.

    Tu as l'air d'avoir compris l'utilisation des paramètres et des variables locales c'est déjà bien !
    Développeur écolo, je suis pour le développement durable.

  18. #18
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    merci mush mais tu ne penses pas qu'il aurait été plus rapide à la base de me dire que mon algo ne marchait pas , je t'aurais fait perdre bcp moins de temps . J'ai traduit ton aglo :

    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 reply(s: STRING): STRING;
    var
     
       i: CARDINAL;
       j: CARDINAL;
       cpt: CARDINAL;
     
    begin
       cpt := 0;
       for i := 1 to length(s) do
          if s[i] = ' ' then
             for j := i to length(s)-1 do
                s[j] = s[j+1];
       cpt := cpt+1;
       length(s) = length(s)-1;
    end;
    reply := s;
    end;
    Compiling chaine2.pas
    chaine2.pas(15,19) Error: Illegal expression
    chaine2.pas(17,27) Error: Illegal expression
    chaine2.pas(19,1) Fatal: Syntax error, "BEGIN" expected but "identifier REPLY" found

  19. #19
    Débutant
    Profil pro
    Inscrit en
    Février 2007
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 450
    Points : 107
    Points
    107
    Par défaut
    Tu as l'air d'avoir compris l'utilisation des paramètres et des variables locales c'est déjà bien !
    oui et j'ai appris aujourd'hui qu'on pouvait mettre plusieurs boucles de suite , c'est juste étrange de rajouter une variable j ...

  20. #20
    Membre confirmé Avatar de Haywire
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2006
    Messages : 462
    Points : 573
    Points
    573
    Par défaut
    Il n'était pas incorrecte, il était juste incomplet.

    la variable j est nécessaire car il faut une nouvelle variable de contrôle pour chaque boucle.
    Tu ne pourrais pas réutiliser i car lorsque tu sortiras de cette boucle, la valeur de i aura changer.
    imagine que le 3e caractere est un espace, i vaut 3, tu rentres dans la seconde boucle, tu vas jusqu'au bout de la chaine donc a la sortie i vaut la longueur de la chaine - 1. Tu te retrouves a nouveau dans la 1ere boucle et i vaut toujours la longueur de la chaine - 1. Ce qui n'est pas correcte.

    Une règle essentielle est de ne jamais modifier la valeur d'une variable de contrôle à l'intérieur de la boucle qu'elle contrôle.

    L'erreur vient du fait que tu as mis: s[j] = s[j+1]; au lieu de s[j] := s[j+1]; (tu as oublié les ':').

    Et une autre erreur mais qui est une erreur de logique et pas une erreur de compilation, c'est que tu dois mettre cpt:= cpt + 1 dans le corps du if
    (Tu augmentes le compteur seulement si tu as rencontré un espace).

    Enfin, tu ne peux pas faire length(s) := length(s)-1 (en plus tu as oublié les ':' à nouveau). Tu ne peux pas donner une valeur à une fonction.
    Pour modifier la longueur il existe une procedure fournie: setlength.
    De plus il ne faut pas toujours diminuer la taille de 1, il peut y a avoir eu plusieurs espaces (si tu rentres une phrase), d'où l'utilité du compteur.

    la procedure setlength prend en arguments(paramètres) la chaine a modifier, et un entier qui représente la nouvelle longueur.

    Il faut donc mettre: setlength(s,length(s)-cpt);

    Voici la version corrigée, tu verras que tu n'étais pas si loin du but:
    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 reply(s: string): string;
    var
      i,j,cpt: cardinal;
    begin
      cpt := 0;
      for i := 1 to length(s) do
        if s[i] = ' ' then
          begin
            for j:= i to length(s)-1 do
              s[j] := s[j+1];
            cpt := cpt +1;
          end;
        setlength(s,length(s)-cpt);
      reply := s;
    end;
    Développeur écolo, je suis pour le développement durable.

Discussions similaires

  1. [WebI XiR2] Suppression d'un espace dans une chaîne de caractères
    Par SGA99 dans le forum Débuter
    Réponses: 6
    Dernier message: 02/12/2010, 17h12
  2. suppression des espaces d'une chaîne de caractère
    Par tubaas dans le forum MATLAB
    Réponses: 6
    Dernier message: 18/03/2010, 20h19
  3. Réponses: 1
    Dernier message: 16/06/2009, 17h32
  4. Suppression des espaces ds une chaîne
    Par petitnuage dans le forum Langage
    Réponses: 2
    Dernier message: 04/06/2006, 15h59
  5. Suppression d'espaces dans une chaîne
    Par dafalri dans le forum Langage
    Réponses: 11
    Dernier message: 20/02/2006, 13h13

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