Somme

Résolu/Fermé
xman - 6 janv. 2013 à 19:23
 xman - 6 janv. 2013 à 20:31
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

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
6 janv. 2013 à 19:38
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...
0
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.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
6 janv. 2013 à 20:24
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.
0
Merciiiiii , un trés grand MERCI :)
0