Ola galera,
estou estudando recursividade e me deparei com a função de Ackermam.
Essa função retorna valores inteiros que crescem assustadoramente, portanto , se eu uso um int ou long como valor de retorno o algoritmo gera um erro.
Minha duvida é como usar a classe java.math.BigInteger para criar inteiros gigantes na saida do algoritmo?
OBS : tentei ler a especificação da classe na API mas meu inglês só tá iniciando :humm:
valeu!
Qual é o algoritmo ?
A classe BigInteger possui metodos como add() para somar, subtract() para subtrair, divide() para dividir, multiply() para multiplicar, etc…
Dê uma olhada na documentação:
http://java.sun.com/javase/6/docs/api/java/math/BigInteger.html
O algoritmo é esse:
class Ackermann {
static int cnt;
public static int ackermann(int m, int n) {
cnt++;
if (m == 0) return n+1;
if (n == 0) return ackermann(m-1, 1);
return ackermann(m-1, ackermann(m, n-1));
}
public static void main(String args[]) {
int m, n;
cnt = 0;
for(int i = 1;i < 20; i++)
{
m = 3;
n = i+1;
System.out.printf("\n%d",ackermann(m,n));
}
}
}
O problema é que ao usar variáveis int ou longint gera-se um erro em tempo de execução pois os valores de saida são muito grandes, acima da capacidade de representação de int ou longint.
Minha duvida é como fazer para no lugar das variáveis int usar um BigInteger que suporta a saida de números grandes.OK? Obrigado.
A classe BigInteger tem o metodo compareTo() que recebe um BigInteger que deseja comparar,veja se esse codigo lhe serve:
public static BigInteger ackermann(BigInteger m, BigInteger n) {
cnt++;
if (m.compareTo(new BigInteger(“0”)) == 0 )
return n.add(new BigInteger(“1”));
if (n.compareTo(new BigInteger(“0”)) == 0)
return ackermann(m.subtract(new BigInteger("-1")), new BigInteger(“1”));
return ackermann(m,n.subtract(new BigInteger("-1")));
}
Tu podera trocar o construtor BigInteger(“String”) por BigInteger(int []) ou long,mas acho que fica mais facil trabalhar com Strings .
Acho que isso vai resolver seu problema já que você deve etá com problema de estouro de mémoria(java heap),realmente é recomendando que você utilize o BigInteger. :lol:
class Ackermann {
static BigInteger cnt;
public static BigInteger ackermann(BigInteger m, BigInteger n) {
cnt.add(BigInteger.ONE);
if (m.equals(BigInteger.ZERO)) return n.add(BigInteger.ONE);
if (n.equals(BigInteger.ZERO)) {
return ackermann(m.subtract(BigInteger.ONE), BigInteger.ONE);
}
return ackermann(
m.subtract(BigInteger.ONE),
ackermann(m, n.subtract(BigInteger.ONE))
);
}
public static void main(String args[]) {
BigInteger m, n;
cnt = BigInteger.ZERO;
m = BigInteger.valueOf(3);
for(int i = 1;i < 20; i++){
n = BigInteger.valueOf(i+1);
System.out.printf("\n%d",ackermann(m,n));
}
}
}
Ai está o algoritmo com BigInteger. Para os casos especificos em que vc precisa usar 1 ou zero deve usar as constantes dadas pelo ppr BigInteger.
Para outros valores deve usar valueOf(). O construtor com String serve para passar numeros muitos grandes que não têm outra forma de serem expressos.
De resto é só usar os métodos apropriados de calculo e comparação (poderiamos usar compareTo() mas o equals é mais prático e explicito )
VALEU MESMO GALERA, É MUITO BOM CONTAR COM GENTE EXPERIENTE E COM VONTADE DE AJUDAR
Colegas,
Em vários topicos eu visualizei que o objetivo deste forum era esclarecer duvias e nao passar a resolução completa, por isso passei o dia hoje tentando resolver o algorítimo abaixo, que nao minha concepção é bem simples. mas nao consegui por completo. Segue abaixo. ele ta retornando 0. nao era pra ele pedir o valor e calcular o mesmo antes de mostrar?
Segue. Qq ajuda vai ser muito bem vinda.
/*
* Main.java
*
* Created on 10 de Fevereiro de 2007, 13:33
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package novoprojeto;
import java.math.BigInteger;
/**
*
* @author LAPTOP 02
*/
public class Main {
/** Creates a new instance of Main */
public Main() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
BigInteger cnt;
// TODO code application logic here
cnt = BigInteger.ZERO;
System.out.print(cnt);
}
private static Object[] ackermann(BigInteger m, BigInteger n) {
BigInteger cnt;
m = BigInteger.valueOf(3);
for(int i = 1;i < 20; i++){
n = BigInteger.valueOf(i+1);
System.out.printf("\n%d",ackermann(m,n));
}
return null;
}
}
Esse é o main. a classe segue abaixo (Coloquei o nome da classe de BigInteger).
import java.math.BigInteger;
class Ackermann {
static BigInteger cnt;
public static BigInteger ackermann(BigInteger m, BigInteger n) {
cnt.add(BigInteger.ONE);
if (m.equals(BigInteger.ZERO)) return n.add(BigInteger.ONE);
if (n.equals(BigInteger.ZERO)) {
return ackermann(m.subtract(BigInteger.ONE), (BigInteger.ONE));
}
return ackermann(
m.subtract(BigInteger.ONE),
ackermann(m, n.subtract(BigInteger.ONE)));
}
}
Não tá dando erro, mas ta vindo zerado.
Abs!
pedir o valor ? o codigo não tem nada que peça valores a ninguem