Fatorial

41 respostas
A

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);
    } 
}

41 Respostas

joede.fadel
faça assim
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);  
     }   
 }

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

dlt

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.

A

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

joede.fadel

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.

A

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

mrcastro

Vc precisa somar o resultado, não?

Acho que tinha que mudar aqui:
#  for (cont=1;cont<=n;cont++){    
   
            fatorial=fatorial*cont;  
                 
         }
pra
for (cont=1;cont<=n;cont++){    
   
            fatorial+=fatorial*cont;  //soma com o valor anterior de fatorial
                
        }

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

A

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

GALACTUS

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.

mrcastro

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

Eu testei aqui e funcionou normalmente…

Valder_Olmo_Correa

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.

mrcastro

Ah, certo. Entendi :slight_smile:

A

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.

T

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

Focao

tem que ser recursivo senão é primata.


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

F
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

B

Focão:
tem que ser recursivo senão é primata.

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

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

Focao

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

B

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

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 - [telefone removido] 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");
    }
}
B

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.

Focao

Bruno Laturner:
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.

Caracas Bruno…
da hora
Deu até saudades das aulas de algorítmo na facu.

Pena que á época não tinha IDE nenhuma era e, c++ na unha hehehe

Fonte guardado para futuras discussões…

parabéns… escovou bit e ainda poliu

Pena que o tópica é fe fatorial, será que da ma migrar esse post pro tópico fibonacci ?

Abçs bom FDS a todos que fritaram os neurônios…

B

Dá sim, mas isso fica como exercício para o leitor :wink:

maquiavelbona

Pena que a melhor maneira de se calcular Fibonacci é O(log n). Talvez já tenham dado a idéia, mas é só para atiçar a curiosidade.
E o problema da recursividade não é necessariamente a memória e sim o tamanho reservado para a Stack.

Até!

Fabio_Kym_Nascimento

O “problema” do fibonacci recursivo é a implementação, se você usar uma recursividade “bem simples” ele vai recalcular todos os valores sempre, pra melhorar isso é só usar um array auxiliar junto com a recursividade, você guarda os valores já calculados no array pra não precisar recalcular pra cada sequencia até atingir a desejada.

Focao

F?io “Kym” Nascimento:
O “problema” do fibonacci recursivo é a implementação, se você usar uma recursividade “bem simples” ele vai recalcular todos os valores sempre, pra melhorar isso é só usar um array auxiliar junto com a recursividade, você guarda os valores já calculados no array pra não precisar recalcular pra cada sequencia até atingir a desejada.

Ok isso mesmo


Mas Isso é a memorização já citado e implementado.
vide acima

public static BigInteger fibMem(int n)
wesley.comput

Boa tarde, segue um exemplo com recursividade. Dá pra melhorar este algoritmo, deixo isso pra vc.

int fat(int n) {
    if(n == 1)
        return 1;
    else
        return n * fat(n - 1);
}
maquiavelbona

Seu algoritmo está errado. Tente fat(0).

Até!

wesley.comput

Primeiramente, esta mais errado ainda, tente fat(n < 0)…

Minha Frase: Boa tarde, segue um exemplo com recursividade. Dá pra melhorar este algoritmo, deixo isso pra vc.

Releia a frase acima e procure se em algum lugar esta escrito que este eh o melhor algoritmo. (tooooma)

Mesmo que ele não trate o valor de entrada igual a zero nao quer dizer que ele esta errado. (tooooma)

Não existe motivos pra calcular o fatorial de zero, isso pode ser verificado na leitura do valor digitado pelo usuário e se for menor ou igual a zero nem precisa chamar o metodo fat(n). (tooooma)

[size=18]Dá pra melhorar este algoritmo, deixo isso pra vcs.[/size]

Só uma dúvida, poquê a melhor maneira de se calcular Fibonacci é O(log n)? Qual a melhor forma de calcular a série de Fibonacci?

maquiavelbona

wesley.comput:
Primeiramente, esta mais errado ainda, tente fat(n < 0)…

Minha Frase: Boa tarde, segue um exemplo com recursividade. Dá pra melhorar este algoritmo, deixo isso pra vc.

Releia a frase acima e procure se em algum lugar esta escrito que este eh o melhor algoritmo. (tooooma)

Mesmo que ele não trate o valor de entrada igual a zero nao quer dizer que ele esta errado. (tooooma)

Não existe motivos pra calcular o fatorial de zero, isso pode ser verificado na leitura do valor digitado pelo usuário e se for menor ou igual a zero nem precisa chamar o metodo fat(n). (tooooma)

[size=18]Dá pra melhorar este algoritmo, deixo isso pra vcs.[/size]

Só uma dúvida, poquê a melhor maneira de se calcular Fibonacci é O(log n)? Qual a melhor forma de calcular a série de Fibonacci?


Ô pessoa, leia o meu comentário. Falei que o algoritmo está errado ( pois está ) e dei um exemplo, agora que se quer que eu corrija para você é pedir demais.
Sim, se uma função está definida para n>=0 ( não existe fatorial de número negativo, andou faltando nas suas aulas? ) e não trata esse caso ela está errada. Não falei que o seu algoritmo era melhor ou pior e sim que está errado. Melhorar não é corrigir ( não a princípio). Se não sabe aceitar críticas, se isole.
A definição de saber se uma função é inútil dado um certo valor não compete fora dela. Já pensou se o nome da função fosse:

int metodoInutilQueVoceDesconheceOQueSejaMasEImportanteParaCalcularOSeuPagamento(int k);

E você tivesse que implementar no seu código? Você tem que saber o que ela faz por dentro ou só o que ela retorna? Não tente me dar aulas de como construir código.

E Fibonacci recursivo é exponencial, usando um caso particular algébrico vira linear e usando-se desse caso algébrico, faz-se um dividir-e-conquistar para tornar-se logarítmico. Agora é só procurar.

Até!
[edits]:pensei mais rápido que escrevi, os edits foram para colocar frases compreensíveis.

B

Melhorando…

int fat (int n) {
    if (n < 0)
        throw new IllegalArgumentException("Fatorial é uma função definida somente dentro do conjunto dos números naturais.");
    else if (n == 0 || n == 1)
        return 1;
    else
        return n * fat(n - 1);
}
Fabio_Kym_Nascimento

Melhorando…

int fat (int n) { if (n < 0) throw new IllegalArgumentException("Fatorial é uma função definida somente dentro do conjunto dos números naturais."); else if (n == 0 || n == 1) return 1; else return n * fat(n - 1); }

Oi, faltou o throws IllegalArgumentException na assinatura do método :stuck_out_tongue:

peczenyj

IllegalArgumentException vem de java.lang.RuntimeException, o que me faz pensar se precisamos ou não adicionar na assinatura do método. :?

Fabio_Kym_Nascimento

Ah é verdade, my bad, achei que não era necessário apenas o handle/declare, não sabia que não precisava nem ir na assinatura do método, boa, aprendi mais uma :oops:

B
Bruno Laturner:
wesley.comput:
Boa tarde, segue um exemplo com recursividade. Dá pra melhorar este algoritmo, deixo isso pra vc.
Melhorando...
int fat (int n) {
    if (n < 0)
        throw new IllegalArgumentException("Fatorial é uma função definida somente dentro do conjunto dos números naturais.");
    else if (n == 0 || n == 1)
        return 1;
    else
        return n * fat(n - 1);
}
Melhorando...
int fat (int n) {
    if (n < 0)
        throw new IllegalArgumentException("Fatorial é uma função definida somente dentro do conjunto dos números naturais.");
    else if (n == 0 || n == 1)
        return 1;
    else
        return n * fat2(n - 1);
}

private int fat2 (int n) {
    if (n == 1)
        return 1;
    else
        return n * fat2(n - 1);
}
J

boa tarde aproveitando o topico, como se faz para somar os digitos do do resultado do fatorial??

no caso 5! é 120

eu tenho q fazer 1+2+0

eu sei que tenho que transformar em string… mas depois/???

leandronsp

Existe uma classe na API que calcula o fatorial? (típico preguiçoso…)

peczenyj

Se existir esta aqui:

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html

B

leandronsp:
Existe uma classe na API que calcula o fatorial? (típico preguiçoso…)

Existe necessidade de ter algo do tipo numa API? Nunca vi algo de útil feito com base em fatoriais.

Lavieri
leandronsp:
Existe uma classe na API que calcula o fatorial? (típico preguiçoso...)

Não sei se existe... mais é algo tão simples o.O
private class MathUtil {

    public static BigInteger fatorial(long n) {
        return fatorial(BigInteger.valueOf(n));
    }

    public static BigInteger fatorial(BigInteger n) {
        if (n.compareTo(BigInteger.ZERO) == -1)
            throw new IllegalArgumentException("N value cannot be less then zero");
        return calculateFatorial(n);
    }

    private static BigInteger calculateFatorial(BigInteger n) {
        return (n.equals(BigInteger.ZERO)) ? BigInteger.ONE : 
            n.multiply(calculateFatorial(n.subtract(BigInteger.ONE))); // o mesmo que n * (n-1)!
    }
}

bastava o ultimo método, so que colocando um método antes de entrar na recursividade, é possivel fazer teste de concistencia, sem ter q fazer N vezes em um recursividade ^^

victorwss

JaVa_MaChInE:
boa tarde aproveitando o topico, como se faz para somar os digitos do do resultado do fatorial??

no caso 5! é 120

eu tenho q fazer 1+2+0

eu sei que tenho que transformar em string… mas depois/???

http://www.guj.com.br/posts/list/15/119727.java#648462

rmendes08

Bruno Laturner:
leandronsp:
Existe uma classe na API que calcula o fatorial? (típico preguiçoso…)

Existe necessidade de ter algo do tipo numa API? Nunca vi algo de útil feito com base em fatoriais.

Caraca … qualquer fórmula básica de combinatória usa fatoriais!

B

rmendes08:
Bruno Laturner:
leandronsp:
Existe uma classe na API que calcula o fatorial? (típico preguiçoso…)

Existe necessidade de ter algo do tipo numa API? Nunca vi algo de útil feito com base em fatoriais.

Caraca … qualquer fórmula básica de combinatória usa fatoriais!

Bem pensado :oops:

Criado 13 de outubro de 2008
Ultima resposta 5 de mar. de 2009
Respostas 41
Participantes 20