Fonction récursive

xman -  
KX Messages postés 19031 Statut Modérateur -
Bonjour,
c'est une fonction récursive pour compter le nombre de voyelles dans une chaine ,
je ne sais pas pourquoi lors de l'exécution de cette fonction le résultat est 0 , qui peut m'aide et MERCI D'AVANCE
function nbv(i:integer;ch:string):integer;
var
n:integer;
begin
n:=0;
if(i<=length(ch)) then
if (upcase(ch[i])in['A','E','U','I','O','Y'])then
begin
n:=n+1;
n:=n+nbv(i+1,ch);
end;
nbv:=n;
end;

2 réponses

  1. KX Messages postés 19031 Statut Modérateur 3 020
     
    Ton problème se situe dans le fait que ton appel récursif est uniquement dans le cas où la lettre est une voyelle. Si c'est une consonne, tu arrêtes la fonction avec le résultat courant. En réalité tu comptes donc le nombre de voyelles au début du mot. si ton mot commence par une consonne alors ça donne 0.

    function nbv(i:integer;ch:string):integer;
    var n:integer;
    begin
        n:=0;
    
        if(i<=length(ch))
        then begin
    
             if (upcase(ch[i]) in ['A','E','U','I','O','Y'])
             then n:=n+1;
          
             n := n+nbv(i+1,ch);
    
             end;
    
        nbv:=n;
    end;

    Remarque : normalement une fonction récursive va toujours du cas le plus compliqué vers le cas le plus simple, tu ne devrais donc pas avoir nbv(i+1,ch); mais nbv(i-1,ch); ce qui tendrait à partir du caractère length(ch) pour progressivement diminuer la complexité et faire un test sur 0, plutôt que "compter" à chaque fois la taille de ch...

    function nbv(i:integer;ch:string):integer;
    begin
        if (i=0)
        then result:=0
        else if (upcase(ch[i]) in ['A','E','U','I','O','Y'])
             then result:= 1+nbv(i-1,ch)
             else result:= nbv(i-1,ch);
    end;
    0
  2. ccm81 Messages postés 11033 Statut Membre 2 434
     
    Bonjour

    Une remarque: le paramètre i n'est pas vraiment indispensable ici

    function nbv(ch:string):word;
    begin
      if ch = '' 
      then nbv := 0
      else
        if upcase(ch[1]) in ['A','E','I','O','U','Y']
        then nbv := 1+nbv(copy(ch,2,length(ch)-1)
        else nbv := nbv(copy(ch,2,length(ch)-1);
    end;


    bonne journée
    0
    1. KX Messages postés 19031 Statut Modérateur 3 020
       
      Je suis d'accord sur le principe, mais ça nécessite de faire des copy alors qu'on peut s'en passer.
      Il est plus simple d'avoir une deuxième fonction qui appelle la première :

      function nbv(ch:string):integer; 
      begin 
          result := nbv(length(ch),ch); 
      end;

      D'ailleurs en Pascal on pourrait mettre les deux fonctions en une seule en utilisant la première fonction comme fonction auxiliaire de la deuxième (à utiliser avec parcimonie) :

      function nbv(ch:string):integer;
      
         function aux(i:integer;ch:string):integer;
         begin
             if (i=0)
             then result:=0
             else if (upcase(ch[i]) in ['A','E','U','I','O','Y'])
                  then result:= 1+aux(i-1,ch)
                  else result:= aux(i-1,ch);
         end;
      
      begin
          result := aux(length(ch),ch);
      end;
      0