目录
斐波那契数列简介
定义:斐波那契数列指的是这样一个数列:
0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368...这个数列从第3项开始,每一项都等于前两项之和。
斐波那契数列(Fibonacci Sequence)又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。在数学上,斐波那契数列以如下被以递推的方法定义:
F(O)=0,F(1)=1,
F(n)=F(n-1)+F(n-2)(n ≥2,n EN*")
实验要求
实验说明:我们这次实验讨论用两种方法:非递归方法和递归方法,求解第n个斐波那契数,完成以下实验任务。
(1)设计并实现一个完整的图形用户界面程序,要求界面上有两个按钮:非递归算法、递归算法。当选择非递归算法后,完成实验任务(2)的要求;当选择递归算法后,完成实验任务(3)的要求。
(2)使用教材2.5节中介绍的迭代算法 Fib(n),在源代码中编写int Fib(int n)函数,实现输入任意非负整数n,求第n个斐波那契数,并显示实验结果。
(3)使用教材2.5节中介绍的递归算法F(n),实现输入任意非负整数n,求第n个斐波那契数,并显示实验结果。
(4)附加任务:前面三个任务完成后,可思考这个问题,在你所用的编程语言中,int型变量能表示的最大正整数是多少?在该范围内的最大的斐波那契数是第几个?请在源代码中适当修改,实现对最大正整数和最大斐波那契数的打印输出。请思考,斐波那契数的递归算法和非递归算法哪个更耗时?为什么?
代码实现
界面和逻辑设计
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.naming.InitialContext;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class WindowActionEvent extends JFrame{
JTextField input;//声明文本框对象
JTextArea show;//声明文本区域对象
JButton b1,b2,b3,b4;//按钮对象
int n,tmp,temp,i=1;//部分方法中用到的变量
public WindowActionEvent()
{
init();//窗体初始化
setVisible(true);//窗体可见
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗口关闭
}
void init()
{
setLayout(new FlowLayout());//流式布局
input=new JTextField(10);//创建文本框
b1=new JButton("递归算法");
b2=new JButton("非递归算法");
b3=new JButton("int型最大整数");
b4=new JButton("int型最大斐波那契数");
show=new JTextArea(5,15);
add(input);//添加文本框内容
add(b1);//添加按钮
add(b2);
add(b3);
add(b4);
add(show);
b1.addActionListener(new ActionListener() {//设置监听
public void actionPerformed(ActionEvent e)
{
String str=input.getText();//键盘输入到文本框,提取出来作为运算的n
n=Integer.parseInt(str);//字符串转换成整型
show.setText("递归,第"+n+"个斐波那契数为"+F(n));//输出在文本框显示
}
}
);
b2.addActionListener(new ActionListener() {//设置监听
public void actionPerformed(ActionEvent e)
{
String str=input.getText();
n=Integer.parseInt(str);
show.setText("第"+n+"个斐波那契数为"+Fib(n));
}
}
);
b3.addActionListener(new ActionListener() {//设置监听
public void actionPerformed(ActionEvent e)
{
show.setText("int最大值为:"+max(tmp));
}
}
);
b4.addActionListener(new ActionListener() {//设置监听
public void actionPerformed(ActionEvent e)
{
show.setText("最大斐波那契数为:"+max_fbnq()+",是第"+(i-1)+"个");
}
}
);
}
int F(int n)//递归
{
if(n<=1)
return n;//0和1有确定的值作为结束条件
else
return F(n-1)+F(n-2);//问题缩小变成算n-1和n-2的和
}
int Fib(int n)//迭代
{
int a=0,b=1,c=0;//初始化变量值】
if(n<=1)
{
return n;
}
else
{
for(int i=1;i<n;i++)//循环迭代到第n个
{
c=a+b;//求下一个斐波那契数
a=b;//改变值从而计算下一个
b=c;
}
}
return c;
}
int max(int tmp)//计算int类型能表示的最大数
{
int tmp1=0;
for(int i=0;i<=30;i++)//Int占4个字节共32位,最高位表示正负,所以是31位从0到30
{
tmp1=tmp1+(1<<i);//二进制移位计算31个全1
}
return tmp1;
}
int max_fbnq()
{
for(i=1;i<100;i++)//循环计算
{
if(Fib(i)<0)//当大于能表示的最大值时,会出现负数,那么出现负数的时候最大值就是前一个数字即最大的斐波那契数
return Fib(i-1);
}
return 0;
}
}
主方法测试
public class main {
public static void main(String args[])
{
WindowActionEvent win=new WindowActionEvent();
win.setBounds(100,100,500,500);
win.setTitle("斐波那契数列");
}
}
运行结果
算法分析
递归斐波那契数列算法效率分析框架
斐波那契数列:0、1、1、2、3、5、8、13、21...... 这个数列从第三项开始,每一项都等于前两项之和,用递归的思想试计算第n个斐波那契数。
采用递归算法问题逐渐向下递减缩小。
F(n) { If n<=1 return 1 If n>2 return F(n-1)+F(n-2) }
输入一个确定的数,即输入规模为1
F(n-1)+F(n-2)
最差效率:n>2,执行F(n-1)+F(n-2)+1次 最优效率:n<2,执行0次 平均效率:2^n
C(n)=2^n-1
O(2^n) | |
斐波那契数列迭代算法效率分析框架 1、问题描述: 斐波那契数列:0、1、1、2、3、5、8、13、21...... 这个数列从第三项开始,每一项都等于前两项之和,用迭代的思想试计算第n个斐波那契数。 2、算法:
采用迭代算法循环交换赋值直到循环结束。
Fib(n) { long a=0,b=0,c=1; If n==0 return 0 If n==1 return 1 For i=1 to n do { c=a+b; a=b; b=c;} return c; } 3、确定输入规模: 输入一个确定的数,即输入规模为1 4、确定基本操作: C=a+b 5、执行次数还与哪些因素有关? 最差效率:n>1,执行n次 最优效率:n<=1,执行1次 平均效率:n 6、执行次数的求和公式: C(n)=n-1 7、确定增长次数类型: O(n) |