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

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

LintCode--斐波纳契数列

笔试面试算法题
  • Tina_yaoyao
  • Tina_yaoyao
  • 2015年10月28日 10:11
  • 1946

查找斐波纳契数列中第N个数

题目描述所谓的斐波纳契数列是指: 前2个数是 0 和 1 。第 i 个数是第 i-1 个数和第i-2 个数的和。 斐波纳契数列的前10个数字是: 0, 1, 1, 2, 3, 5, 8, 13,...
  • eric_doug
  • eric_doug
  • 2016年07月11日 11:54
  • 948

【C#】项目1--斐波那契数列(人生中第一个C#程序)

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespac...
  • u012369143
  • u012369143
  • 2014年09月04日 15:47
  • 1758

LintCode336斐波那契数列的解析

今天算是我正式想要入坑oj的第一天,之前只是一年半前在hdoj上面刷过几道水题,然后就因为各种懒拖烦,将算法和数据结构落下了 今年大二暑假,感觉有点方了,只学过javaweb,能做一些小型的小项目而...
  • Tsingsn
  • Tsingsn
  • 2016年07月02日 11:59
  • 681

C# 斐波那契数列

//// /// /// 斐波那契数列,递归算法 /// /// 第num位数的值 /// public s...
  • taoerit
  • taoerit
  • 2016年11月22日 10:25
  • 2281

LintCode 查找斐波纳契数列中第 N 个数

所谓的斐波纳契数列是指: 前2个数是 0 和 1 。第 i 个数是第 i-1 个数和第i-2 个数的和。 斐波纳契数列的前10个数字是: 0, 1, 1, 2, 3, 5, 8, 1...
  • sinat_30440627
  • sinat_30440627
  • 2016年03月23日 14:17
  • 2377

算法之路(三)----查找斐波纳契数列中第 N 个数

算法题目 查找斐波纳契数列中第 N 个数。 所谓的斐波纳契数列是指: * 前2个数是 0 和 1 。 * 第 i 个数是第 i-1 个数和第i-2 个数的和。 斐波...
  • u011619283
  • u011619283
  • 2016年11月02日 11:10
  • 1011

LintCode入门练习——366. 斐波纳契数列

斐波纳契数列是指: 前2个数是 0 和 1 。第 i 个数是第 i-1 个数和第i-2 个数的和。 给定 1,返回 0 给定 2,返回 1 给定 10,返回 34 以上是Lint...
  • a862229403
  • a862229403
  • 2018年01月23日 01:41
  • 12

【LintCode 入门】366. 斐波纳契数列

1.问题描述: 查找斐波纳契数列中第 N 个数。 所谓的斐波纳契数列是指: 前2个数是 0 和 1 。第 i 个数是第 i-1 个数和第i-2 个数的和。 斐波纳契数列的前10...
  • sinat_23133783
  • sinat_23133783
  • 2018年01月15日 12:51
  • 28

递归和非递归方法实现斐波那契数列

介绍 斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibonacci[1]  )以兔子繁殖为例子而引入,故又称为“兔...
  • buptlrw
  • buptlrw
  • 2016年04月13日 11:32
  • 1950
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:斐波纳契数列不同实现比较
举报原因:
原因补充:

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