Ir ao conteúdo
  • Cadastre-se

Leilson Frantchelino

Membro Júnior
  • Posts

    5
  • Cadastrado em

  • Última visita

posts postados por Leilson Frantchelino

  1. Opa, valeu Simon, mais uma contribuição. Alterado.

     

    Program FatRecursivo ;
    Var n, i: integer;
    
    Function Fat(n:integer): integer ;
      Begin
       if n = 0 then
         Fat:= 1     
       else 
         Fat:= n * Fat(n-1)
      End;
    
    Begin  
      write('Entre com o valor de n: ');
      readln(n);
     for i:=1 to n do
      begin
        writeln('Fatorial de ',i,' = ' , Fat(i) );  
      //readkey;
      end;
    End.

     

  2. Tudo bem Simon.

    1 hora atrás, Simon Viegas disse:

    De onde tirou que Fat(4) seria igual a 4? ou seja, não tem como saber o valor Fat(4) antes de executar o Fat(4), que por sua vez precisa esperar o Fat(3)... etc. Logo, não faz sentido essa suposição.

    Aqui eu quis exemplificar de como seria o valor do parâmetro como se tivesse passado 5, assim Fat:= n * Fat(n-1), n recebe 5, então seria Fat:=5*Fat(4). Acabei esquecendo de por o 5 como exemplo. Desculpa.

     

    1 hora atrás, Simon Viegas disse:

    Quem vai retornar ao ponto inicial não é a função, mas sim o programa (o computador)... que está com a execução de varias funções em cascata. Detalhe: uma execução de uma função recursiva nada mais é como se fosse uma execução de outra função qualquer... apenas existe o detalhe de ser ela mesma.

    Certinho Simon.

     

    1 hora atrás, Simon Viegas disse:

    ATENÇÃO: ser diferente não tem relação com o "n-1"... mesmo se fosse um valor igual, cada função terá um n diferente (não pode confundir isso!).

    Sim, a cada iteração, terá a cópia de n com seu devido valor., n1, n2, n3...

     

    Obrigado Simon. A intenção do post foi ajudar a quem tem dúvida e, como deixei escrito no post, gostaria de ajuda em consertar erros. Você foi um que contribui com isto.

     

    Fiz uma pequena mudança no código. A cada iteração, trás o valor.

    Program FatRecursivo ;
    Var n, i: integer;
    
    Function Fat(n:integer): integer ;
      Begin
       if n = 0 then
         Fat:= 1     
       else 
         Fat:= n * Fat(n-1)
      End;
    
    Begin  
      write('Entre com o valor de n: ');
      readln(n);
     for i:=1 to n do
      begin
        writeln('Fatorial de ',i,'! = ' , Fat(i) );  
      //readkey;
      end;
    End.

     

    adicionado 9 minutos depois
    1 hora atrás, Simon Viegas disse:

    No caso da recursividade, cada vez que uma nova instância é finalizada, a instância anterior vai receber o valor resultante dela.

    Esqueci de comentar essa parte. Simon, é realmente isso, no seu exemplo, você demonstrou isso. Foi o que tentei expor também aqui:

    Desempilha (recursivamente) 
    1:=1*Fat(1)=1 
    1:=2*Fat(1)=2 
    2:=3*Fat(2)=6 
    6:=4*Fat(6)=24 
    24:=5*Fat(24)=120

     

    • Curtir 1
  3. Muita gente, inclusive eu, tem dificuldade em entender o que o programa faz nas iterações de recursividade. Vou mostrar abaixo o que eu entendi ao fazer Debugger do código de fatorial recursivo. Me corrijam se minha interpretação estiver errada, pois já quebrei a cabeça tentando entender a lógica. Esse foi o resultado mais lógico que cheguei "debugando" linha por linha.

    Program FatRecursivo ;
    Var n: integer;
    
    Function Fat(n:integer): integer ;
      Begin
       if n = 0 then
         Fat:= 1;     
       else 
         Fat:= n * Fat(n-1)
      End;
    
    Begin  
      write('Entre com o valor de n: ');
      readln(n);
      writeln('Valor de fat(n) => ', Fat(n));
      readkey;
    End.
    Empilha (iteração)                                             Desempilha (recursivamente)                                                                                           
    Fat:= 5*Fat(4)  Chama a fuction novamente passando o 4         1:=1*Fat(1)=1
    Fat:= 4*Fat(3)  Chama a fuction novamente passando o 3         1:=2*Fat(1)=2                                                                                                                                      
    Fat:= 3*Fat(2)  Chama a fuction novamente passando o 2         2:=3*Fat(2)=6                                                                                                                 
    Fat:= 2*Fat(1)  Chama a fuction novamente passando o 1         6:=4*Fat(6)=24                                                                                                                          
    Fat:= 1*Fat(0) - if(n = 0) then Fat:=1                         24:=5*Fat(24)=120                                                                             

    Quando o programa principal chama a Function pela primeira vez, o Fat:= não recebe nada, pois ao chegar em Fat(n-1), a Function é chamada novamente, não permitindo que Fat:= receba o valor do cálculo de Fat:=n*Fat(n-1). Se calculasse, Fat:= iria receber 20, resultado de  Fat:=5*Fat(4). Então, a iteração vai acontecendo até “n” ser 0, condição if n = 0.

     

    Ao terminar a iteração (if n = 0 then Fat:=1), a Function vai fazer a ordem inversa, de baixo para cima. Agora sim Fat:= vai receber os valores do cálculo, pois a Function precisa retornar ao ponto da primeira chamada (Fat:= 5*Fat(4)). Fazendo a ordem inversa, o primeiro cálculo é (Fat:= 1*Fat(0)) que foi a última iteração. Devido ao comando if n = 0 then Fat:=1, o primeiro cálculo inicia-se assim 1:=1*Fat(1) = 1. Agora, uma após a outra, Fat:= recebe o valor do cálculo e, n é recuperado, mantendo o mesmo valor da iteração.

     

    Obs: o programa Principal aguarda por um retorno da Function Fat que, por sua vez, se executa recursivamente para chegar a uma resposta. Em toda iteração (recursiva), de Function Fat, o valor do parâmetro n é diferente (resultado de (n-1)). Quando a chamada recursiva se encerra, o programa precisa voltar ao ponto em que a chamada ocorreu (de baixo para cima), recuperando os valores das variáveis locais.

    • Curtir 1
  4. Em 19/07/2019 às 10:32, Simon Viegas disse:

    Olá @Leilson Frantchelino.

     

     

    Sobre:

     

     

    Nesse trecho 2 pontos:

    1. esse begin e end; são desnecessários (não estão vinculados a algo). Basta removê-los;
    2. no Pascal, para "contextos padrões", usam-se apenas readln(). Apenas inserir "ln" aí. (não use read(), pois pode causar comportamentos indesejados)

     

    Além desses pontos, acho que só faltou "validar" se é um número romano, por exemplo. Se eu inserir XM vai retornar 990, que obviamente está errado.

     

    Assim como se eu inserir BBMP ("Bora Bahia Minha *****") vai retornar 1000... idem!

     

    Outra ponto que faz parte da validação seria a questão de letras minúsculas. Pode ou não pode? o que fazer quando alguém inserir?

    program romanos1;
    
    
    var
       romano: array[0..7] of char;
       valor: array[0..7] of integer;
       algromano: string;
       i, j, ant, soma: integer;
       letras: char;
       roma:string;
       valorsoma: integer;
       opcao: char;
       
     
    
    begin
         
    
    	   romano[0] := ' ';  
    	   romano[1] := 'I';
    	   romano[2] := 'V';
    	   romano[3] := 'X';  
    	   romano[4] := 'L';
    	   romano[5] := 'C';
    	   romano[6] := 'D';
         romano[7] := 'M';
    	
    	   valor[0] := 0; 
    	   valor[1] := 1;
    	   valor[2] := 5;
    	   valor[3] := 10;
    	   valor[4] := 50;
    	   valor[5] := 100;
    	   valor[6] := 500;
    	   valor[7] := 1000;
    	 
    	 opcao:='s';
    	   while (opcao='s') do
    	   begin
    	   ant:=0;
         soma:=0;
         algromano:='';
         letras:=' ';
         roma:='';
         valorsoma:=0;
    	   
    	 //aqui verifica se o algarismo romano digitado é válido     
    	     writeln ('Digite o algorismo romano:');
    	     readln (algromano);
    	      algromano:=upcase(algromano);
    	     	for i:=1 to length(algromano) do 
    	      begin
    	      clrscr;
    	              letras:= (algromano[i]);	  	                          			                                                                                                              
    	                  if ((letras<>romano[1]) and (letras<>romano[2]) and (letras<>romano[3]) and (letras<>romano[4]) and (letras<>romano[5]) and (letras<>romano[6]) and (letras<>romano[7])) then begin
    	                        writeln('Algarismo romano inválido, digite novamente.');
    	                        readln (algromano);
    	                        algromano:=upcase(algromano);
    													letras:=' ';
    													i:=0;                
    	                  end;             
    	                  
    	      end;
    	 
    	 //aqui converte o algarismo romano em decimal
    	for i:=1 to length(algromano) do 
    	  begin
    	      letras:= upcase(algromano[i]);
    	  	  for j:=0 to 7 do  
    				    begin
                    if letras = romano[j] then 
    						       begin
                           soma := soma + (valor[j]);
                           if ant < (valor[j]) then begin
                           soma := soma - ant*2;
                           ant:= (valor[j]);
                       end else begin  
                       ant:= (valor[j]);
    	            end; 
    				    end;
    	           	  
              end;        
          	  
    	 end; 
    	     // aqui valida o algarismo romano
    			  valorsoma:=soma;
    			  while (valorsoma>=1000) do
    			    begin
    			        roma:= roma+'M';
    			        valorsoma:=valorsoma-1000;
    			    end; 
    					while (valorsoma>=900) do
    			    begin
    			        roma:= roma+'CM';
    			        valorsoma:=valorsoma-900;
    			    end;
    					while (valorsoma>=500) do
    			    begin
    			        roma:= roma+'D';
    			        valorsoma:=valorsoma-500;
    			    end;
    					while (valorsoma>=400) do
    			    begin
    			        roma:= roma+'CD';
    			        valorsoma:=valorsoma-400;
    			    end;
    					while (valorsoma>=100) do
    			    begin
    			        roma:= roma+'C';
    			        valorsoma:=valorsoma-100;
    			    end;
    					while (valorsoma>=90) do
    			    begin
    			        roma:= roma+'XC';
    			        valorsoma:=valorsoma-90;
    			    end;
    					while (valorsoma>=50) do
    			    begin
    			        roma:= roma+'L';
    			        valorsoma:=valorsoma-50;
    			    end;
    					while (valorsoma>=40) do
    			    begin
    			        roma:= roma+'XL';
    			        valorsoma:=valorsoma-40;
    			    end;
    					while (valorsoma>=10) do
    			    begin
    			        roma:= roma+'X';
    			        valorsoma:=valorsoma-10;
    			    end;
    					while (valorsoma>=9) do
    			    begin
    			        roma:= roma+'IX';
    			        valorsoma:=valorsoma-9;
    			    end;
    					while (valorsoma>=5) do
    			    begin
    			        roma:= roma+'V';
    			        valorsoma:=valorsoma-5;
    			    end;
    					while (valorsoma>=4) do
    			    begin
    			        roma:= roma+'IV';
    			        valorsoma:=valorsoma-4;
    			    end;
    					while (valorsoma>=1) do
    			    begin
    			        roma:= roma+'I';
    			        valorsoma:=valorsoma-1;
    			    end;
    					   
              if (roma=algromano) then
              writeln('O valor decimal do algarismo romano ',algromano,' é: ',soma) else
              writeln('O algarismo romano ',algromano,' não é válido, o valor correto para ',soma,' é ',roma);  
    					writeln(''); 
              writeln('Deseja fazer a conversão novamente? s/n');
              readln(opcao);
              clrscr;
       end; 
    	 clrscr;      
          writeln('Sistema encerrado.');    
    end.

     

    • Curtir 1
  5. Fiz um bem simples em Pascal. Não testei totalmente, mas esta funcionando. Se precisar que eu coloque os comentários do que faz cada variável, avisa.

     

    program romanos;
    
    
    var
       romano: array[0..7] of char;
       valor: array[0..7] of integer;
       algromano: string;
       i, j, ant, soma, n: integer;
       letras: char;
       
    
    begin
         ant:=0;
         soma:=0;
         algromano:=' ';
         letras:=' ';
    
           romano[0] := ' ';
           romano[1] := 'I';
           romano[2] := 'V';
           romano[3] := 'X';
           romano[4] := 'L';
           romano[5] := 'C';
           romano[6] := 'D';
         romano[7] := 'M';
        
           valor[0] := 0;
           valor[1] := 1;
           valor[2] := 5;
           valor[3] := 10;
           valor[4] := 50;
           valor[5] := 100;
           valor[6] := 500;
           valor[7] := 1000;
         begin     
             writeln ('Digite o algorismo romano:');
             read (algromano);
         end;
        
        for i:=1 to length(algromano) do
          begin
              letras:= algromano[i];
                for j:=0 to 7 do  
                        begin
                    if letras = romano[j] then
                                   begin
                           soma := soma + (valor[j]);
                           if ant < (valor[j]) then
                           soma := soma - ant*2;
                           ant:= (valor[j]);
                       end;  
             
                        end;
         end;
          write ('O resultado é:',soma);
    end.

     

    • Curtir 2

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!