斐波纳契数列不同实现比较

原创 2013年12月05日 18:28:45

斐波纳契数列形如:0,1,2,3,5,8,13,....。该序列的通用方程是:Fib(n)=Fib(n-1)+Fib(n-2).
1.使用递归

unsigned RecursiveFib(unsigned n)
{
	if (n <= 1)
		return n;
	return RecursiveFib(n-1) + RecursiveFib(n-2);
}


eg:RecursiveFib(0xFF); 信不信由你,这个简单函数的时间复杂度是指数级的,它非常低效。

2.使用循环

unsigned RecursiveFib(unsigned n)
{
	if (n <= 1)
		return n;

	unsigned f_2 = 0;
	unsigned f_1 = 1;
	unsigned f;
	for (unsigned i = 2; i <= n; i ++)
	{
		f = f_1 + f_2;
		f_2 = f_1;
		f_1 = f;
	}

	return f;
} 


eg:RecursiveFib(0xFFFFFF);解决了1中低效的问题。

3.使用模板函数

template<unsigned N> struct Fib
{
	enum
	{
		Val = Fib<N-1>::Val + Fib<N-2>::Val
	};
};

template <> struct Fib<0> {enum{Val = 0};};
template <> struct Fib<1> {enum{Val = 1};};

#define RecursiveFib3(n) Fib<n>::Val 


eg:RecursiveFib(4);
关于此模板化版本需要注意以下几点:
.模板函数并不是真正的函数--它是叫作Val的枚举整数,在编译期递归生成。语句Val = Fib<N-1>::Val + Fib<N-2>::Val不常见,但是合法。
.Fib被定义为结构,以简化标记。在默认情况下结构数据是公用的,这也正是我们所需要的。
.模板参数N用于指定函数的输入。这种模板参数的使用并不常见,但完全可行。例数,std::bitset<N> 用N的数值作为它的模板参数来定义表示位域的位数。数字参数必须在编译期被获知,如果当i还是可变的变量时调用RecursiveFib(i),则会产生编译错误。
.要中止递归,需要正确地处理结束条件。对于斐波纳契数来说,结束条件就是当N为0和1时。在模板中处理基本情况的方法是使用模板特化。标记了template<>的,表示为模板特化。当N为0和1时,Val=N.

分析编译程序如何计算RecursiveFib(4):

=Fib<4>::Val
=Fib<3>::Val + Fib<2>::Val
=Fib<2>::Val + Fib<1>::Val + Fib<1>::Val + Fib<0>::Val
=Fib<1>::Val + Fib<0>::Val + 1 + 1 + 0
=1 + 0 + 1 + 1 + 0
=3


由于所有的输入在编译期都确定了,所以编译程序可以将RecursiveFib(N)换算为常量。换句话来说,编译程序可以生成与以下完全等价的代码:

std::cout<<3;//std::cout<<RecursiveFib(4)

该方法可以成为你C++工具包中有用工具。你很可能会有指数级运行时间不能降为常数级运行时间的情况,通过使用模板无编程,就可以通过增加额外的编译时间来降低程序的执行时间。对于游戏来说,执行时间通常比编译时间更重要,所以这项技术也将非常有用。

相关文章推荐

Fibonacci series(斐波纳契数列)的几种常见实现方式

费波那契数列(意大利语:Successione di Fibonacci),又译费波拿契数、斐波那契数列、斐波那契数列、黄金分割数列。 在数学上,费波那契数列是以递归的方法来定义: F_0=0 F...

AS3实现经典算法(一) 斐波纳契数列

package{ /* 斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……在数学上, 斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-...

看看PHP迭代器的内部执行过程以及用PHP迭代器来实现一个斐波纳契数列

下面我们来了解如何实现一个自定义的迭代器,然后再开始慢慢理解迭代器的内部工作原理。先来看一个官方的例子: class myIterator implements Iterator { p...

斐波纳契数列分析和实现

斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一...
  • abcdad
  • abcdad
  • 2017年03月20日 10:12
  • 106

用JavaScirpt实现斐波纳契数列最简洁方式

斐波纳契数列(Fibonacci Sequence),又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=...

斐波纳契数列

  • 2006年02月23日 09:05
  • 3KB
  • 下载

java斐波纳契数列

  • 2012年09月27日 16:55
  • 359B
  • 下载

青蛙跳台阶——斐波纳契数列

(1)一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法。 分析:1)当n = 1, 只有1中跳法;当n = 2时,有两种跳法;当n = 3...

斐波纳契数列求和算法

  • 2013年03月23日 23:02
  • 48KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:斐波纳契数列不同实现比较
举报原因:
原因补充:

(最多只允许输入30个字)