Fatorial

Tenho um programa que pede o seginte:

Faça um programa que leia um número N, maior que 0, e imprima o fatorial do número
lido.

No caso eu digitei o numero 5,quando foi solicitado para mim…e o resultado deu certo 120…mais quando eu digito outros numeros aparece 120 sempre…

import javax.swing.*;
public class Fatorial {
        
     
    public static void main(String[] args) {
        int n,fatorial=1,cont;
        
        n=Integer.parseInt(JOptionPane.showInputDialog("digite o numero"));
        
        for (cont=1;cont<=n;cont++){
        	cont++;
        	fatorial=cont++*cont++*cont++*cont;
        	
        }
       System.out.println ("o fatorial "+fatorial);
    } 
}

faça assim

[code]

import javax.swing.*;
public class Fatorial {

 public static void main(String[] args) {  
     int n,fatorial=1,cont;  
       
     n=Integer.parseInt(JOptionPane.showInputDialog("digite o numero"));  

     for (cont=1;cont<=n;cont++){  

         fatorial=fatorial*cont;
           
     }  
    System.out.println ("o fatorial "+fatorial);  
 }   

}[/code]

o seu codigo da errado pq sempre vc vai estar multiplicando o cont e não está acumulando o valor fatorial do numero.

inicialize as variaveis separadamente.

int n;
int fatorial;
int cont;

a lógida de dentro do seu loop está errada, tente fazer do jeito que o joede.fadel disse.
Alternativamente, vc pode tentar calcular o fatorial recursivamente.

Fiz como você falou,mais da 48 no final…Isso dando o valor de 5 quando é pedido.

foi mal eu esqueci de tirar o incremento dentro do seu for
quando vc utiliza o comando for vc nao precisa incrementar
o atributo dentro dele.

Mais com isso o resultado fica 720…E se eu for colocar int fatorial=0…No final fica 0.

Vc precisa somar o resultado, não?

Acho que tinha que mudar aqui:

[code]# for (cont=1;cont<=n;cont++){

        fatorial=fatorial*cont;  
             
     }  [/code]

pra

[code]
for (cont=1;cont<=n;cont++){

        fatorial+=fatorial*cont;  //soma com o valor anterior de fatorial
            
    }  [/code]

pq desse jeito ele ta pegando apenas o último valor e não o acumulado de antes

Também não, o resultado fica 2520…e no caso é pra dar 120…

Ei tíu, faça com BigInteger pra não dar estouro de dados no seu programa, e se o alguem derrepente digitar 5555???
Seu computador vai explodir hahaha.
Eu tentei fazer o seu programa com BigInteger, vÊ se funciona:

// Programa que calcula o fatorial de um número

package fatorial;

import javax.swing.JOptionPane;
import java.math.BigInteger;

public class Fatorial 
{
    public static void main(String[] args) 
    {
        String num=JOptionPane.showInputDialog("Digite um número");
        int n=Integer.parseInt(num);
        int i;
        BigInteger fatorial=new BigInteger("1");
        BigInteger multiplicador=new BigInteger("1");
        BigInteger mais1=new BigInteger("1");
        
        for(i=1;i<=n;i++)
        {
            fatorial=fatorial.multiply(multiplicador);
            multiplicador=multiplicador.add(mais1);
        }
        JOptionPane.showMessageDialog(null,"O Fatorial de "+n+" é:\n"+fatorial, 
                "FATORIAL",JOptionPane.PLAIN_MESSAGE);
    }
}

Vê se a bagaça funciona que eu não testei, se o seu computador explodir, eu não sei de nada em.

Fuiiiiiii.

Alexdino, qual é o problema no código do joede.fadel?

Eu testei aqui e funcionou normalmente…

mrcastro, não há problema nenhum de lógica com o programa do joede.fadel
Funciona bem. O único problema é que ele declarou a variável fatorial como sendo int. E isso faz com que haja um estouro na memória para números altos, até o 16 funciona bem, mas tente com o 17, dará um número negativo. Iso por que o tipo inteiro não comporta a faixa de valores para o fatorial de números acima de 17.
para resolver esse problema basta declarar a variável fatorial como double.

Ah, certo. Entendi :slight_smile:

oi pessoal,
eu fiz o prog pra fatorial e funcionou ate 10:

for(int n=1;int fatorial=1; n<=10; n++){[size=9][/size]
fatorial= n*fatorial;
System.out.println("Fatorial de " +n+ " é "+fatorial);
}

No entanto quando pus n<=40 os resultados sairam errados.
Então mudei o tipo de int para long e o resultado continuou errado.

Alguem pode ajudar ? valeu, Andrea.

40! = 8,1591528324789773434561126959612e+47 que é um número que não cabe em um long.

tem que ser recursivo senão é primata.


http://www.guj.com.br/posts/list/43115.java

		int numAux = numero, aux;
		numero--;
		for (aux = numero; aux > 1; aux--) {
			numAux = numAux * aux;
		}

essa parte calcula o fatorial e guarda no numAux

ta certinho

[quote=Focão]tem que ser recursivo senão é primata.

http://www.guj.com.br/posts/list/43115.java
[/quote]

Recursividade é a a pior forma de calcular um fatorial, fibonacci, etc.

Nooossa sem ofensa Bruno

Essa tem que ir pro tápico que tá bombando, das frases de gerente de projetos

while é for é mais elegante que isso ?

inteiro Fibonacci (inteiro k)
{
se k = 1: devolvo 1;
se k = 2: devolvo 1;
devolvo Fibonacci(k - 1) + Fibonacci (k - 2);
}

A recursividade é a forma mais fácil de se implementar uma sequência,

no entanto a menos eficiente dependendo do tamanho da lista
Mas se tiver disponível muita memória não tem problema

então pode usar a memoização para conseguir uma maior eficiência com a implementação mais simples.

só Phiton faz isso java da pra fazer com HashMap

A reiteração é a forma aberta da recursividade e o algoritmo que os programadores buscam,
muitas vezes apenas porque desconhecem outras soluções.

A matriz característica é uma boa solução, se a potência de matrizes for implentada de forma binária
caso contrário se torna muito ineficiente.
De qualquer forma, é possível calcular a função fechada, que resolve a sequência por álgebra linear,
método altamente eficiente e que não sofre muita variação ao longo da projeção cartesiana.

em complexidade pensa assim
= (O(n-1)) + 1
= (O(n-2) + 1) + 1
= O(n-2) + 2
= (O(n-3) + 1) + 2
= O(n-3) + 3

forma geral, O(n) = O(n-k) + k, 1  k  n
Como k é o número do fatorial, fazendo n = k, reduzimos a O(n) = n

[quote=Focão]no entanto a menos eficiente dependendo do tamanho da lista
Mas se tiver disponível muita memória não tem problema[/quote]

Pois é. O problema é que o tamanho da lista nem precisa ser grande para o método recursivo falhar espetacularmente com um StackOverflow. Ninguém pensa em escalabilidade né? Só por que a complexidade do problema é linear, não quer dizer que todas as implementações são igualmente performáticas.

Se quiser mostrar o melhor, poste resultados como este:

Fibonacci Normal: 102334155 Reentradas: 204668309 - 19863913431 ns Fibonacci Memoizado: 102334155 Reentradas: 79 - 437206 ns Fibonacci Tail Recursion: 102334155 Reentradas: 41 - 123480 ns Fibonacci Iterativo: 102334155 Reentradas: 38 - 99174 ns

O código:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class Fibonacci
{
    private static long reentradas;

    public static BigInteger fib(int n)
    {
        reentradas++;
        if (n <= 2)
            return BigInteger.ONE;
        else
            return fib(n - 1).add(fib(n - 2));
    }

    public static BigInteger fibTail(int n, BigInteger current, BigInteger next)
    {
        reentradas++;
        if (n == 0)
            return current;
        else
            return fibTail(n - 1, next, current.add(next));
    }
    private static List<BigInteger> list = new ArrayList<BigInteger>(0);

    public static BigInteger fibMem(int n)
    {
        reentradas++;
        if (n < list.size())
            return list.get(n);
        else
        {
            BigInteger resultado;

            if (n <= 1)
                resultado = new BigInteger(new Integer(n).toString());
            else
                resultado = (fibMem(n - 2).add(fibMem(n - 1)));

            list.add(resultado);

            return resultado;
        }
    }

    public static BigInteger fibIter(int n)
    {
        if (n <= 2)
        {
            reentradas++;
            return BigInteger.ONE;
        }

        BigInteger a = BigInteger.ONE;
        BigInteger b = BigInteger.ONE;

        for (int i = 3; i <= n; i++)
        {
            reentradas++;
            BigInteger c = a.add(b);
            a = b;
            b = c;
        }
        return b;
    }

    public static void main(String[] args)
    {
        final int numero = 40;
        long t = System.nanoTime();

        System.out.println("Fibonacci Normal: " + fib(numero));
        System.out.println("Reentradas: " + reentradas + " - " + (System.nanoTime() - t) + " ns");
        t = System.nanoTime();

        reentradas = 0;
        System.out.println("Fibonacci Memoizado: " + fibMem(numero));
        System.out.println("Reentradas: " + reentradas + " - " + (System.nanoTime() - t) + " ns");
        t = System.nanoTime();

        reentradas = 0;
        System.out.println("Fibonacci Tail Recursion: " + fibTail(numero, BigInteger.ZERO, BigInteger.ONE));
        System.out.println("Reentradas: " + reentradas + " - " + (System.nanoTime() - t) + " ns");
        t = System.nanoTime();

        reentradas = 0;
        System.out.println("Fibonacci Iterativo: " + fibIter(numero));
        System.out.println("Reentradas: " + reentradas + " - " + (System.nanoTime() - t) + " ns");
    }
}

Sobre os 4 métodos acima:

Fibonacci normal falha com 50 recursões
Tail recursion falha com 10000
Memoizado falha com 100000

E mesmo com 1 milhão de iterações, a versão iterativa continua indo.