小菲波那契数的计算程序

 
小菲波那契数的计算程序
刚开始写程序的人往往不愿意对问题进行细致的分析,他们喜欢多用一些空间来表示问题的结构,从而简化程序的控制部分。为计算菲波那契数,定义一个数组f,f[i]用于存放第i项菲波那契数。一个初学者的程序看起来可能是下面的样子:
// Program: Fib_0
#define MAX_SIZE           20
 
int Fib(int n)
{
    int f[MAX_SIZE+1];
    int i;
 
         f[0] = f[1] = 1;
    for (i = 2; i <= n; i++)
                   f[i] = f[i - 1] + f[i - 2];
 
         return f[n];
}
在核心循环中,f[i]的计算仅需用到f[i-1]和f[i-2],如果用两个变量f0、f1分别表示f[i-1]和f[i-2],通过增加一点点控制就可以省去数组f,相应的程序为:
// Program: Fib_1
// 定义宏SWAP,交换两个变量的值
#define SWAP(x, y)            (x^=y^=x^=y)
 
int Fib(int n)
{
    int f0, f1;
    int i;
 
         if (n == 0 || n == 1) return 1;
 
         f0 = f1 = 1;
 
         // 在进入循环时,f0=f[i-2],f1=f[i-1],出循环时f0=f[i-1],f1=f[i]
         for (i = 2; i <= n; i++)
         {
                   f0 += f1;
                   SWAP(f0, f1);
         }
    return f1;
}
SWAP通过计算完成两个变量值的交换目的,其依据为:
             x^(x^y)=y
             y^(x^y)=x
“^”表示异或操作。核心循环可以有多种写法,例如:可引入一个中间变量来完成f0、f1的交换任务:
// Program: Fib_2
int Fib(int n)
{
    int f0 = 1, f1 = 0, f;
    int i;
 
    for (i = 0; i <= n; i++)
         {
                   f = f0 + f1;
                   f0 = f1;
                   f1 = f;
         }
    return f;
}
或者利用菲波那契数的性质得到
// Program: Fib_3
int Fib(int n)
{
    int f0 = 1, f1 = 0;
    int i;
 
    for (i = 0; i <= n; i++)
         {
                   f1 += f0;
                   f0 = f1 - f0;
         }
 
    return f1;
}
也可以不引入任何中间变量,而是在进入循环时,判断i是否偶数,若2|i,则保证f0=f[i-2],f1=f[i-1],否则,f0=f[i-1],f1=f[i-2]。相应的程序为:
// Program: Fib_4
int Fib(int n)
{
    int f0 = 0; f1 = 1;
    int flag = 0;
    int i;
 
    for (i = 0; i <= n; i++)
         {
                   if (flag == 0)
                       f0 = f0 + f1;
                   else
                        f1 = f0 + f1;
                   flag = 1 - flag;
         }
 
    if (flag == 0) return f0;
    return f1;
}
在上面的五种计算程序中,考虑到程序逻辑的清晰性和可理解性,程序Fib_2是最可取的。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值