代码改变世界

Java Fibonacci 示例

2022-05-02 10:09  jetwill  阅读(86)  评论(0编辑  收藏  举报

斐波那契数列: 第一、第二个数之后的每个数字都是前两个数之和

Java 8 流

1.1 在Java 8中,我们可以使用Stream.iterate生成斐波那契数列,如下所示:

import java.util.stream.Stream;

public class Main {

	public static void main(String[] args) {
		Stream.iterate(new int[] { 0, 1 }, t -> new int[] { t[1], t[0] + t[1] })
				.limit(10)
				.forEach(x -> System.out.println("{" + x[0] + "," + x[1] + "}"));
	}
}

输出:

{0,1}
{1,1}
{1,2}
{2,3}
{3,5}
{5,8}
{8,13}
{13,21}
{21,34}
{34,55}

观察以上的输出,第一列值是我们想要的。

1.2 最终版本。

import java.util.stream.Stream;

public class Main {

	public static void main(String[] args) {
		Stream.iterate(new int[] { 0, 1 }, t -> new int[] { t[1], t[0] + t[1] })
				.limit(10).map(t -> t[0]).forEach(x -> System.out.println(x));
	}
}

输出:

0
1
1
2
3
5
8
13
21
34

1.3将所有斐波那契数相加

int sum = Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]})
		.limit(10)
		.map(t -> t[0])
		.mapToInt(Integer::intValue)
		.sum();
 
    System.out.println("Total : " + sum);

输出:

Total : 88

1.4以逗号分隔。

import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {

	public static void main(String[] args) {
		String collect = Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]})
                .limit(10)
                .map(t -> t[0])
                .map(String::valueOf) // convert to string
                .collect(Collectors.joining(", "));
 
        System.out.println("Result : " + collect);
	}
}

输出:

Result : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

1.5创建斐波那契数列的功能。

package com.test;

import java.util.List;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;

public class Fibonacci {

	public static List<Integer> getFibonacci(int series) {
		return Stream
				.iterate(new int[] { 0, 1 },
						t -> new int[] { t[1], t[0] + t[1] }).limit(series)
				.map(n -> n[0]).collect(toList());
	}

	public static void main(String[] args) {
		List<Integer> fibonacci = getFibonacci(10);
		fibonacci.forEach(x -> System.out.println(x));
	}
}

输出:

0
1
1
2
3
5
8
13
21
34

1.6 int和long类型不足以存储较大的斐波那契数。 以下是BigInteger示例,用于查找前十万斐波纳契数。

package com.test;

import java.math.BigInteger;
import java.util.stream.Stream;

public class Fibonacci {

	public static BigInteger getFibonacci(int series) {
		return Stream
				.iterate(new BigInteger[] { BigInteger.ZERO, BigInteger.ONE },
						t -> new BigInteger[] { t[1], t[0].add(t[1]) })
				.limit(series).map(n -> n[0]) 
				.reduce((a, b) -> b).orElse(BigInteger.ZERO);

	}

	public static void main(String[] args) {
		System.out.println(Fibonacci.getFibonacci(10_000));
//		System.out.println(Fibonacci.getFibonacci(3));

	}

}

输出

2079360823713349807211264898864283682508703609401590311968... //2090 digits!!!, too long to display here

2.递归循环

2.1 Java递归循环示例创建斐波那契数列。 仅适合演示,此递归循环很慢。

package com.test;
 
public class Fibonacci {
 
    public static int fib(int n) {
        if (n == 1) return  0;
        if (n == 2) return  1;
        return fib(n - 1) + fib(n - 2);
    }
    
    public static void main(String[] args) {
 
        for (int i = 1; i <= 10; i++) {
            System.out.println(fib(i));
        }
 
    }
 
 
}

输出

0
1
1
2
3
5
8
13
21
34

2.2工作原理

fib(n) = fib(n - 1) + fib(n - 2);
... 
fib(5) = fib(4) + fib(3);
fib(4) = fib(3) + fib(2);
fib(3) = fib(2) + fib(1);
fib(2) = 1
fib(1) = 0

3.普通循环

3.1 Java普通循环查找斐波那契数,简单易行。

package com.test;
 
import java.math.BigInteger;
 
public class Fibonacci {
 
    public static int fib(int n) {
        if (n == 1) return 0;
        if (n == 2) return 1;
 
        int pre = 1, prepre = 0, result = 0;
 
        for (int i = 3; i <= n; i++) {
            result = pre + prepre;
            prepre = pre;
            pre = result;
        }
 
        return result;
    }
 
    public static BigInteger fib2(int n) {
        if (n == 1) return BigInteger.ZERO;
        if (n == 2) return BigInteger.ONE;
 
        BigInteger prepre = BigInteger.ZERO, pre = BigInteger.ONE, sum=BigInteger.ZERO;
 
        for (int i = 3; i <= n; i++) {
            sum = pre.add(prepre);
            prepre = pre;
            pre = sum;
        }
 
        return sum;
    }
 
    public static void main(String[] args) {
 
        for (int i = 1; i <= 10; i++) {
            System.out.println(fib(i));
        }
 
        System.out.println("---");
 
        for (int i = 1; i <= 10; i++) {
            System.out.println(fib2(i));
        }
 
        System.out.println("---");
 
        System.out.println(fib(100)); //overflow
        System.out.println(fib2(100));
    }
 
}

输出

0
1
1
2
3
5
8
13
21
34
---
0
1
1
2
3
5
8
13
21
34
---
-889489150
218922995834555169026

注意 请使用BigInteger存储斐波那契数字,以避免出现溢出问题。

翻译自: https://mkyong.com/java/java-fibonacci-examples/