Can anyone here please help me to reduce the time complexity of this code:
public static int a(int number) {
if ((number == 0) || (number == 1))
return number;
else
return a(number - 1) + a(number - 2);
}
public static void main(String[] args) {
System.out.print("Enter the count of Fibonacci series: ");
int cap = new Scanner(System.in).nextInt();
System.out.println("Output: ");
for (int i = 1; i <= cap; i++){
System.out.printf("%d\n", a(i));
}
}
You can store previously calculated values, so if you try calculate fibonnaci(100) you don't calculate fibonacci(50) about 100 times.
Pseudo code:
dictA = {}
a(n):
if n in dictA:
return dictA[n]
else if n <= 1:
return n
else:
val = a(n-1) + a(n-2)
dictA[n] = val
return val
It is quite simple to add some cache, where you will store already calculated values. If you want exactly the recursive algorithm the idea will be the same - just check in the beginning of routine if the value already calculated. If yes - return it from cache, else - start calculate (do not forget to save it after calculation ended).
public class Fibbonaci {
public static long calc(int n) {
List<Integer> cache = new ArrayList<>();
cache.add(1);
cache.add(2);
for (int i = 2; i < n; i++) {
cache.add(cache.get(i - 1) + cache.get(i - 2));
}
return cache.get(n - 1);
}
public static void main(String[] args) {
IntStream.range(1, 10)
.forEach(n -> System.out.println("Fibb " + n + " = " + calc(n)));
}
}
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I am trying to write a recursive algorithm to compute Fibonacci numbers. However, the program struggles with printing out the results.
My idea was to store each calculated value into an array (so the algorithm should be faster).
My desired output:
The fibonacci of n = 1 is fn= 1
The fibonacci of n = 2 is fn= 2
The fibonacci of n = 3 is fn= 2
The fibonacci of n = 4 is fn= 3
...
The fibonacci of n = 8 is fn= 21
public class fibonacciCalculator {
static int[] arr = new int[50];
static int fibo (int n, int arr[]) {
if ( n == 0 ) {
return 0;
}else if ( n == 1 ) {
return 1;
}
if ( arr[n-1] == 0) {
arr[n-1] = fibo(n-1, arr);
}
if ( arr[n-2] == 0) {
arr[n-2] = fibo(n-2, arr);
}
return arr[n-1] + arr[n - 2];
}
public static void main(String[] args) {
for (int i = 1; i == 8; i++) {
if (arr [i] == 0) {
fibo(i, arr);
int x = arr[i];
String a = String.format("The fibonacci of n = %d is fn= %d", i , x);
System.out.println(a);
}
}
}
}
You can do this without declaring an array. This way, the intermediate values are stored in the execution stack:
public class fibonacciCalculator {
static int fibo (int n) {
if ( n == 0 ) {
return 0;
} else if ( n == 1 ) {
return 1;
} else {
return fibo(n-2) + fibo(n-1);
}
}
public static void main(String[] args) {
for (int i = 1; i <= 8; i++) {
int x = fibo(i);;
String a = String.format("The fibonacci of n = %d is fn= %d", i , x);
System.out.println(a);
}
}
}
Here is one way to do it.
public int[] fib(int values[], int count) {
if (count <= 0) {
return values;
}
int k = values.length + 1;
values = Arrays.copyOf(values, k);
values[k - 1] = values[k - 2] + values[k - 3];
return fib(values, count - 1);
}
But an even better way is to memoize the values as you create them. This permits you to start calculating at the last computed terms and then continue until you meet your goal. If you specify a value less than the number computed, only those requested are returned.
A defensive copy of the list is used so you can't taint the returned sublist.
List<Integer> fibs = new ArrayList(List.of(0, 1));
public List<Integer> fib(int count) {
int s = fibs.size();
if (count < s) {
// return a defensive copy to protect cached values.
return new ArrayList<>(fibs.subList(0, count));
}
int e = fibs.get(s - 1) + fibs.get(s - 2);
fibs.add(e);
return fib(count);
}
Okay to close this up I will post the working code.
Maybe that will help anyone else.
public class fibonacciCalculator {
static int[] arr = new int[48];
static int fibo (int n, int arr[]) {
if ( n == 1|| n == 2 ) {
return 1;
}else if ( n == 0 ) {
return 0;
}
if (arr[n-1] == 0) {
arr[n-1] = fibo(n-1, arr);
}
if (arr[n-2] == 0) {
arr[n-2] = fibo(n-2, arr);
}
return arr[n-1] + arr[n - 2];
}
public static void main(String[] args) {
for (int i = 1; i <= arr.length-1; i++) {
if (arr [i] == 0) {
arr[i] = fibo(i, arr);
System.out.print("The Fibonacci number " + i);
System.out.println(" is: " + arr[i]);
}
}
}
}
However ... int will exceed its limit at Fibonacci 48. If you want higher values int should be replaced to long.
but after that well don't know.. :D
Greetings Synix
This is my another solution where the output is shown as expected
public class Logic2 {
public static void main(String[] args) {
long sum = 0;
calculation key = new calculation();
sum = key.sum(3, 1000);
System.out.print(sum);
}
}
class calculation {
long total = 0;
public long sum(int num, int limit) { //multples of num less than limit
int number = Integer.valueOf(limit / num);
if (limit % num == 0) {
number -= 1;
}
total = (number / 2) * (2 * num + (number - 1) * num);
return total;
}
}
I wrote this code myself. It seems everything fine but I am not getting the required output. Why is this so?
It looks like your math is just slightly wrong. Try breaking it up into smaller parts to confirm you're getting what you're expecting. A working example which returns 166833
public static void main(String[] args) {
int a = 3, N = 1000;
System.out.println("Sum of multiples of " + a +
" up to " + N + " = " +
calculate_sum(a, N));
}
private static int calculate_sum(int a, int N) {
// Number of multiples
int m = N / a;
// sum of first m natural numbers
int sum = m * (m + 1) / 2;
// sum of multiples
return a * sum;
}
If you split your method up the same way, you will see where you've missed the mark slightly.
public class Logic2 {
public static void main(String[] args) {
long sum = 0;
calculation key = new calculation();
sum = key.sum(3, 1000);
System.out.print(sum);
}
}
class calculation {
long total = 0;
public long sum(int num, int limit) { //multples of num less than limit
int number = Integer.valueOf(limit / num);
if (limit % num == 0) {
number -= 1;
}
total=((number)*(2*num+(number-1)*num))/2;
//previouslly total = (number / 2) * (2 * num + (number - 1) * num);
return total;
}
}
I figured out the bug myself. In that, Total if we write (number/2) then it will give integer value due to which I was not getting the required output. Anyways, Thanks everyone for at list viewing my post, I appreciate it. :)
Here is my implementation of the fibonacci sequence using java
/**
* Returns nth fibonacci number
*/
public class fib {
public static void main(String[] args){
System.out.println(fibonacci(12));
}
public static int fibonacci(int n) {
if (n == 0){
return 0;
} else if (n == 1){
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
}
But visualization of this method using recursion made me think it would be a lot faster.
Here is a visualization of fib(5). http://imgur.com/a/2Rgxs
But this got my thinking, notice at the bottom when we bubble up from the bottom of the recursive path we calculate fib(2), fib(3) and fib(4) but then we recalculate fib(3) on the very top right branch. So I was thinking when we are bubbling back up why not save fib(3) calculated from the left branch so we don't do any calculations on the right branch like my method currently does, like a hashtable while coming back up.
My question is, how do I implement this idea?
When you want to add the HashMap and stay with your original approach, try this:
static HashMap<Integer, Integer> values = new HashMap<Integer, Integer>();
public static void main(String[] args){
values.put(0, 0);
values.put(1, 1);
System.out.println(fibonacci(12));
}
public static int fibonacci(int n) {
if (values.containsKey(n)){
return values.get(n);
} else {
int left = values.containsKey(n - 1) ? values.get(n - 1) : fibonacci(n - 1);
values.put(n - 1, left);
int right = values.containsKey(n - 2) ? values.get(n - 2) : fibonacci(n - 2);
values.put(n - 2, right);
return left + right;
}
}
This approach could be very fast if you call it more often because the fibonacci results are already stored in the values (for sure this could also be done with other approaches):
public static void main(String[] args){
values.put(0, 0);
values.put(1, 1);
System.out.println(fibonacci(12));
System.out.println(fibonacci(11));
System.out.println(fibonacci(10));
}
For a fast calculation, you do not need recursion at all - just shift the intermediate results
public static int fibonacci(int n) {
if (n == 0) {
return 0;
} else {
int npp = 0; // pre-previous number
int np = 1; // previouse number
int r = 1; // current number, eventually the result
for (int i = 2; i <= n; i++) {
r = np + npp;
npp = np;
np = r;
}
return r;
}
}
In order to avoid repeated calculations, you can use dynamic programming. BTW, this is not a memory optimized solution, but it can be faster than the recursive one.
public static int fibonacci(int n)
{
int f[] = new int[n+1];
for (int i = 0; i <= n; i++) {
if(i == 0 || i == 1) {
f[i] = i;
}
else {
f[i] = f[i-1] + f[i-2];
}
}
return f[n];
}
I have to write a program that takes a number from the user and then displays the prime factors of the number. This is the program I have so far:
public static void main(String[] args) {
int a = getInt("Give a number: ");
int i = 0;
System.out.println("Your prime factors are: " + primeFactorization(a, i));
}
public static int getInt(String prompt) {
int input;
System.out.print(prompt);
input = console.nextInt();
return input;
}
public static int primeFactorization(int a, int i) {
for (i = 2; i <= a ; i++) {
while (a % i == 0) {
a /= i;
}
}
return i;
}
}
I can't figure out how to get it to print out the list of numbers. Any help is appreciated.
You should return a List<Integer> not a single int, and there is no point in i being an argument. A correct method is
public static List<Integer> primeFactorization(int a) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 2; i <= a ; i++) {
while (a % i == 0) {
list.add(i);
a /= i;
}
}
return list;
}
While #Paul Boddington's answer is better in most cases (i.e. if you are using the values afterwards), for a simple program like yours, you could add all of the factors to a string and return the string. For example:
public static String primeFactorization(int a) {
String factors = "";
for (int i = 2; i <= a ; i++) {
while (a % i == 0) {
factors += i + " ";
a /= i;
}
}
return factors;
}
I am trying to write a program that give an output as prime decomposition of a given number. However, my code gives correct answer as an output of "2**2**2**2**2**5**7**7**11*" but I want it specific output as "(p1**n1)(p2**n2)...(pk**nk)". Here's my code:
public class PrimeDecomp
{
public static String factors(int n)
{
String ans = "";
for (int i = 2; i <= n; i++)
{
if (n % i == 0)
{
// checks if i is a divisor of num
ans += i + "**";
// writes i in prime factorization
n = n/i;
// since it is written down, num=num/i
i--;
// just in case their are multiple factors of same number.
// For example, 12=2*2*3
}
}
return (ans.substring(0, ans.length() - 1));
}
public static void main(String[] args)
{
System.out.println(PrimeDecomp.factors(86240));
}
}
You almost got it, instead of computing one factor at a time, compute all for the same factor and count them:
public static String factors(int n)
{
String ans = "";
int count = 0;
for (int i = 2; i <= n; i++)
{
// Reset the counter
count = 0;
/*
* Instead of only processing on factor, we process them all and
* count them
*/
while (n % i == 0)
{
count++;
n = n / i;
}
// If we have at least processed one add it to the string
if (count == 1)
{
ans += "(" + i + ")";
} else if (count > 0)
{
ans += "(" + i + "**" + count + ")";
}
}
return ans;
}
Since you are manipulating a string quite often in a loop, you should use StringBuilder