Somme

Résolu
Bonjour,

S'il vous plait aidez moi , je ne sais pas où est l'erreur dans cette procédure
procedure somme(mat:matrice;nc,nl,i,j:integer;var s:integer);
begin
s:=0;
if i<=nl then
if j<= nc then
begin
s:=s+mat[i,j];
somme(mat,nc,nl,i,j+1,s);
end
else
somme(mat,nc,nl,i+1,1,s);
end;
Merci d'avance

1 réponse

  1. Modérateur
    Il n'y a pas d'erreur (ça compile), donc il va falloir expliquer ce qu'est censé faire ton code pour trouver ce qui ne fonctionne pas comme tu le voudrais...
    1. lors de l'exécution le résultat est toujours 0
      program matr;
      uses wincrt;
      type
      Matrice=array[1..20,1..20]of integer;
      var
      Mat:Matrice;
      l,c,nl,nc,s:integer;

      Procedure Saisie(var nl,nc:integer);
      begin
      writeln('Donner le nombre de lignes');
      readln(nl);
      writeln('Donner le nombre de colonnes');
      readln(nc);
      end;

      Procedure Remplissage_Mat(var Mat:Matrice;nc,nl,i,j:integer);
      begin
      if i<=nl then
      if j<=nc then
      begin
      write('Donner Mat[',i,',',j,'] ');
      readln(Mat[i,j]);
      remplissage_mat(mat,nc,nl,i,j+1);
      end
      else
      remplissage_mat(mat,nc,nl,i+1,1);
      end;

      procedure affiche (mat:matrice;nc,nl:integer);
      var
      i,j:integer;
      begin
      for i:=1 to nl do
      begin
      writeln;
      for j:=1 to nc do
      write(Mat[i,j]:4);
      end;
      end;

      procedure somme(mat:matrice;nc,nl,i,j:integer;var s:integer);
      begin
      s:=0;
      if i<=nl then
      if j<= nc then
      begin
      s:=s+mat[i,j];
      somme(mat,nc,nl,i,j+1,s);
      end
      else
      somme(mat,nc,nl,i+1,1,s);
      end;

      BEGIN
      {$M 63000,000}
      saisie(nl,nc);
      remplissage_mat(mat,nc,nl,1,1);
      clrscr;
      affiche(mat,nc,nl);
      writeln;
      somme(mat,nc,nl,1,1,s);
      write(s);
      end.
    2. Modérateur
      Il faut faire attention à l'ordre où s est modifié, toi tu le réinitialises toujours à 0, à chaque appel, alors que cette affectation devrait avoir une seule fois. De plus tous les ajouts des cases devraient avoir lieu après quand ils ont actuellement lieu avant l'appel récursif ! Voici une correction de ton code :

      procedure somme(mat:matrice;nc,nl,i,j:integer;var s:integer); 
      begin
      if i<=nl
      then begin
           if j<=nc
           then begin
                somme(mat,nc,nl,i,j+1,s);
                s:=s+mat[i,j];
                end
           else somme(mat,nc,nl,i+1,1,s);
           end
      else s:=0;
      end;

      Remarque : normalement la récursivité se fait en diminuant la difficulté (donc en diminuant la taille de la matrice au fur et à mesure) alors que ta récursivité l'augmente.
      Du coup tu as beaucoup de paramètres à gérer, alors qu'on pourrait en avoir beaucoup moins :

      function sommeR(var mat:matrice; nc,nl:integer):integer;
      
          procedure aux(i,j:integer);
          begin
              if i=0
              then result:=0
              else if j=0
                   then aux(i-1,nc)
                   else begin
                        aux(i,j-1);
                        result+=mat[i,j];
                        end;
          end;
      
      begin
          aux(nl,nc);
      end;

      Remarque : il y a une manière itérative évidente pour faire ce calcul :

      function sommeI(var mat:matrice; nc,nl:integer):integer;
      var i,j:integer;
      begin
          result:=0;
          for i:=1 to nl do
          for j:=1 to nc do
              result+=mat[i,j];
      end;

      Exemple de programme de test :

      var mat:matrice; s:integer;
      begin
        mat[1,1]:=1; mat[1,2]:=2; mat[1,3]:=3;
        mat[2,1]:=4; mat[2,2]:=5; mat[2,3]:=6;
        mat[3,1]:=7; mat[3,2]:=8; mat[3,3]:=9;
        
        somme(mat,3,3,1,1,s);
        writeln(s); // 45
        
        writeln(sommeR(mat,3,3)); // 45
        writeln(sommeI(mat,3,3)); // 45
        
        readln;
      end.
    3. Merciiiiii , un trés grand MERCI :)