Think in Java之斐波那契數列
斐波納契數列(Fibonacci Sequence),又稱黃金分割數列。
指的是這樣一個數列:1、1、2、3、5、8、13、21、……這個數列從第三項開始,每一項都等于前兩項之和。
在數學上,斐波納契數列以如下被以遞歸的方法定義:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)在現代物理、準晶體結構、化學等領域,斐波納契數列都有直接的應用。
斐波那契數列的***,是意大利數學家列昂納多·斐波那契(Leonardo Fibonacci)。
與黃金分割的關系
有趣的是:這樣一個完全是自然數的數列,通項公式卻是用無理數來表達的。而且當n趨向于無窮大時,后一項與前一項的比值的小數部分越來越逼近黃金分割0.618. 1÷1=1,2÷1=2,3÷2=1.5,5÷3=1.666...,8÷5=1.6,…………,89÷55=1.6181818…,…………233÷144=1.618055…75025÷46368=1.6180339889…...
越到后面,這些比值越接近黃金比。
證明:
a[n+2]=a[n+1]+a[n]。
兩邊同時除以a[n+1]得到:
a[n+2]/a[n+1]=1+a[n]/a[n+1]。
若a[n+1]/a[n]的極限存在,設其極限為x,
則lim[n->;∞](a[n+2]/a[n+1])=lim[n->;∞](a[n+1]/a[n])=x。
所以x=1+1/x。
即x²=x+1。
所以極限是黃金分割比..
如果你看到有這樣一個題目:
某人把一個8*8的方格切成四塊,拼成一個5*13的長方形,故作驚訝地問你:為什么64=65?
其實就是利用了斐波那契數列的這個性質:5、8、13正是數列中相鄰的三項,事實上前后兩塊的面積確實差1,只不過后面那個圖中有一條細長的狹縫,一般人不容易注意到。
在楊輝三角中隱藏著斐波那契數列
斐波那契數列的整除性與素數生成性
每3個數有且只有一個被2整除,
每4個數有且只有一個被3整除,
每5個數有且只有一個被5整除,
每6個數有且只有一個被8整除,
每7個數有且只有一個被13整除,
每8個數有且只有一個被21整除,
每9個數有且只有一個被34整除,
.......
我們看到第5、7、11、13、17、23位分別是素數:5,13,89,233,1597,28657(第19位不是)
斐波那契數列的素數無限多嗎?
斐波那契數列的個位數:一個60步的循環
11235,83145,94370,77415,61785.38190, 99875,27965,16730,33695,49325,72910…
斐波那契數列中是否存在無窮多個素數?[維基百科]
在斐波那契數列中,有素數:
2,3,5,13,89,233,1597,28657,514229,433494437,2971215073,99194853094755497,1066340417491710595814572169,19134702400093278081449423917……
目前已知***素數是第81839個斐波那契數,一共有17103位數。
相關的數學問題
1.排列組合
有一段樓梯有10級臺階,規定每一步只能跨一級或兩級,要登上第10級臺階有幾種不同的走法?
這就是一個斐波那契數列:
登上***級臺階有一種登法;登上兩級臺階,有兩種登法;登上三級臺階,有三種登法;登上四級臺階,有五種登法……
1,2,3,5,8,13……所以,登上十級,有89種走法?! ?/p>
類似的,一枚均勻的硬幣擲10次,問不連續出現正面的可能情形有多少種?
答案是(1/√5)*{[(1+√5)/2]^(10+2) - [(1-√5)/2]^(10+2)}=144種。
2.數列中相鄰兩項的前項比后項的極限
當n趨于無窮大時,F(n)/F(n+1)的極限是多少?
這個可由它的通項公式直接得到,極限是(-1+√5)/2,這個就是黃金分割的數值,也是代表大自然的和諧的一個數字。
3.求遞推數列a(1)=1,a(n+1)=1+1/a(n)的通項公式
由數學歸納法可以得到:a(n)=F(n+1)/F(n),將斐波那契數列的通項式代入,化簡就得結果。
4.兔子繁殖問題(關于斐波那契數列的別名)
斐波那契數列又因數學家列昂納多·斐波那契以兔子繁殖為例子而引入,故又稱為“兔子數列”?! ?/p>
一般而言,兔子在出生兩個月后,就有繁殖能力,一對兔子每個月能生出一對小兔子來。如果所有兔都不死,那么一年以后可以繁殖多少對兔子?
我們不妨拿新出生的一對小兔子分析一下:
***個月小兔子沒有繁殖能力,所以還是一對
兩個月后,生下一對小兔民數共有兩對
三個月以后,老兔子又生下一對,因為小兔子還沒有繁殖能力,所以一共是三對
?。? 依次類推可以列出下表:
經過月數 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
幼仔對數 |
1 |
0 |
1 |
1 |
2 |
3 |
5 |
8 |
13 |
21 |
34 |
55 |
89 |
成兔對數 |
0 |
1 |
1 |
2 |
3 |
5 |
8 |
13 |
21 |
34 |
55 |
89 |
144 |
總體對數 |
1 |
1 |
2 |
3 |
5 |
8 |
13 |
21 |
34 |
55 |
89 |
144 |
233 |
幼仔對數=前月成兔對數
成兔對數=前月成兔對數+前月幼仔對數
總體對數=本月成兔對數+本月幼仔對數
可以看出幼仔對數、成兔對數、總體對數都構成了一個數列。這個數列有關十分明顯的特點,那是:前面相鄰兩項之和,構成了后一項。
這個數列是意大利中世紀數學家斐波那契在<;算盤全書>;中提出的,這個級數的通項公式,除了具有a(n+2)=an+a(n+1)的性質外,還可以證明通項公式為:an=(1/√5)*{[(1+√5)/2]^n-[(1-√5)/2]^n}(n=1,2,3.....) `````
可惜本人是文科生,看不懂也不記得那些所謂的數學公式了,以前素材只摘選感興趣的部分。
來源于百度:http://baike.baidu.com/view/816.htm
我只感興趣的是后面這幾段代碼的實現:
- package com.tudou.t1;
- import java.math.BigInteger;
- import java.util.Scanner;
- /**
- * 斐波那契數列 1,2,3,5,8,13,21....[]
- *
- * @author lz
- *
- */
- public class Fibonacci {
- public static void main(String[] args) {
- fib();//常規算法
- System.out.println(compute2(5));//計算第n個斐波那契數列的數
- fibHign();// Java語言程序(高精度,約一秒鐘計算第20000個數值)
- }
- private static void fib() {
- int x = 1, y = 1;
- System.out.println(x);
- for (int i = 1; i <= 5; i++) {
- System.out.println(y);
- y = x + y;
- x = y - x;
- }
- }
- // n為第n個斐波那契數列的數
- public static BigInteger compute2(int n) {
- if (n == 1 || n == 2) {
- return BigInteger.ONE;
- }
- BigInteger num1 = BigInteger.ONE;
- BigInteger num2 = BigInteger.ONE;
- BigInteger result = BigInteger.ZERO;
- for (int i = 2; i < n; i++) {
- result = num1.add(num2);
- num2 = num1;
- num1 = result;
- }
- return result;
- }
- // Java語言程序(高精度,約一秒鐘計算第20000個數值)
- private static void fibHign() {
- Scanner s = new Scanner(System.in);
- System.out.print("請輸入一個整數:");
- int n = s.nextInt();
- do {
- cul(n);
- n = s.nextInt();
- } while (n > 0);// 當n<=0時終止
- }
- private static void cul(int n) {
- BigIntT b = new BigIntT();
- BigIntT a = new BigIntT();
- b.formatBigInt("1");
- a.formatBigInt("2");
- if (n == 1 || n == 2) {
- System.out.println(1);
- return;
- }
- int i = 3;
- for (; i <= n; i++) {
- if (i % 2 > 0)
- b.add(a);
- else
- a.add(b);
- }
- BigIntT t = null;
- if (i % 2 > 0)
- t = b;
- else
- t = a;
- for (int j = t.getPos(); j < 100000; j++)
- System.out.print(t.getBase(j));
- System.out.println();
- }
- }
- class BigIntT {
- int max = 100000;
- private byte[] base = new byte[max];
- private int pos = max;
- public void formatBigInt(String arr) {
- int l = arr.length();
- if (l == 0)
- return;
- int tmp = l - 1;
- for (int i = max - 1; i >= max - l; i--) {
- base[i] = (byte) (arr.charAt(tmp--) - '0');
- pos--;
- }
- }
- public void add(BigIntT right) {
- int bigger = this.getPos() > right.getPos() ? right.getPos() : this
- .getPos();
- pos = bigger;
- for (int i = max - 1; i >= pos - 2; i--) {
- int t = this.base[i] + right.getBase(i);
- if (t >= 10) {
- this.base[i] = (byte) (t % 10);
- this.base[i - 1] += t / 10;
- if (i - 1 < pos)
- pos = i - 1;
- } else {
- this.base[i] = (byte) t;
- }
- }
- }
- public int getPos() {
- return pos;
- }
- public byte getBase(int index) {
- return base[index];
- }
- }
控制臺輸出結果為:
1 1 2 3 5 8 5
請輸入一個整數:500
139423224561697880139724382870407283950070256587697307264108962948325571622863290
691557658876222521294125
感興趣的朋友,可以玩一下。偶爾玩玩這些也很過癮呢。
原文鏈接:http://blog.csdn.net/yaerfeng/article/details/7279210
【編輯推薦】