写一个函数,输入n,求斐波那契数列(Fibonacci)的第n项,斐波那契数列的定义如下:
第一种方法就是我们在学习C或者C++语言时接触到的递归调用,程序源代码如下:
#include
#include
#include
#include
using std::cin;
using std::cout;
using std::endl;
using std::clock_t;
long long Fibonacci(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
class throwErrow1{};
int main()
{
for (int i = 0; i < 4; i++)
{
cout << "请输入正整数n,求斐波那契数列的第n项:" ;
int n = 0;
cin >> n;//读取数值n
if (n < 0)
{
cout << "输入数据出错,抛出储物,程序停止运行!!!" << endl;
throw throwErrow1{};
}
DWORD dsStart = GetTickCount();//windows下实现毫秒级
clock_t start = clock();//开始时间
long long result = Fibonacci(n);
clock_t finish = clock();//结束时间
DWORD dsFinish = GetTickCount();//windows下实现毫秒级
cout << "结果是:" << result << ",\t共耗时:" << (static_cast(finish - start) / CLOCKS_PER_SEC)*1000.0 << "毫秒" << ",windows系统级时间函数:" << dsFinish - dsStart << "毫秒" << endl;
}
system("pause");
return 0;
}
请输入正整数n,求斐波那契数列的第n项:10
结果是:55, 共耗时:0毫秒,windows系统级时间函数:0毫秒
请输入正整数n,求斐波那契数列的第n项:20
结果是:6765, 共耗时:0毫秒,windows系统级时间函数:0毫秒
请输入正整数n,求斐波那契数列的第n项:30
结果是:832040, 共耗时:110毫秒,windows系统级时间函数:109毫秒
请输入正整数n,求斐波那契数列的第n项:40
结果是:102334155, 共耗时:6990毫秒,windows系统级时间函数:6989毫秒
请按任意键继续. . .
通过上述分析我们发现,提高效率的一种途径就是避免重复计算,下面采用循环的方法记性计算:
#include
#include
#include
using std::cin;
using std::cout;
using std::endl;
using std::clock_t;
long long Fibonacci2(int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
{
long long first = 1;
long long second = 1;
long long result = 1;
for (int i = 2; i < n; i++)
{
result = first + second;
first = second;
second = result;
}
return result;
}
}
class throwError2{};
int main()
{
for (int i = 0; i < 5; i++)
{
int n = 0;
cout << "请输入正整数n" << endl;
cin >> n;
if (n < 0)
{
cout << "输入数据错误,抛出错误,程序停止执行!!!" << endl;
throw throwError2{};
}
DWORD dwStart = GetTickCount();
long long result = Fibonacci2(n);
DWORD dwFinish = GetTickCount();
cout << "斐波那契数列第" << n << "项的结果为:" << result << ",\t共耗时" << dwFinish - dwStart << "毫秒!!!" << endl;
}
system("pause");
return 0;
}
请输入正整数n
40
斐波那契数列第40项的结果为:102334155, 共耗时0毫秒!!!
请输入正整数n
50
斐波那契数列第50项的结果为:12586269025, 共耗时0毫秒!!!
请输入正整数n
60
斐波那契数列第60项的结果为:1548008755920, 共耗时0毫秒!!!
请输入正整数n
70
斐波那契数列第70项的结果为:190392490709135, 共耗时0毫秒!!!
请输入正整数n
80
斐波那契数列第80项的结果为:23416728348467685, 共耗时0毫秒!!!
请按任意键继续. . .
此外,还有一种时间复杂度为O(logn)但不够试用的解法,这里就不说明了。。。
#include
#include
// ====================方法1:递归====================
long long Fibonacci_Solution1(unsigned int n)
{
if (n <= 0)
return 0;
if (n == 1)
return 1;
return Fibonacci_Solution1(n - 1) + Fibonacci_Solution1(n - 2);
}
// ====================方法2:循环====================
long long Fibonacci_Solution2(unsigned n)
{
int result[2] = { 0, 1 };
if (n < 2)
return result[n];
long long fibNMinusOne = 1;
long long fibNMinusTwo = 0;
long long fibN = 0;
for (unsigned int i = 2; i <= n; ++i)
{
fibN = fibNMinusOne + fibNMinusTwo;
fibNMinusTwo = fibNMinusOne;
fibNMinusOne = fibN;
}
return fibN;
}
// ====================方法3:基于矩阵乘法====================
#include
struct Matrix2By2
{
Matrix2By2
(
long long m00 = 0,
long long m01 = 0,
long long m10 = 0,
long long m11 = 0
)
:m_00(m00), m_01(m01), m_10(m10), m_11(m11)
{
}
long long m_00;
long long m_01;
long long m_10;
long long m_11;
};
Matrix2By2 MatrixMultiply
(
const Matrix2By2& matrix1,
const Matrix2By2& matrix2
)
{
return Matrix2By2(
matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10,
matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11,
matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10,
matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11);
}
Matrix2By2 MatrixPower(unsigned int n)
{
assert(n > 0);
Matrix2By2 matrix;
if (n == 1)
{
matrix = Matrix2By2(1, 1, 1, 0);
}
else if (n % 2 == 0)
{
matrix = MatrixPower(n / 2);
matrix = MatrixMultiply(matrix, matrix);
}
else if (n % 2 == 1)
{
matrix = MatrixPower((n - 1) / 2);
matrix = MatrixMultiply(matrix, matrix);
matrix = MatrixMultiply(matrix, Matrix2By2(1, 1, 1, 0));
}
return matrix;
}
long long Fibonacci_Solution3(unsigned int n)
{
int result[2] = { 0, 1 };
if (n < 2)
return result[n];
Matrix2By2 PowerNMinus2 = MatrixPower(n - 1);
return PowerNMinus2.m_00;
}
// ====================测试代码====================
void Test(int n, int expected)
{
if (Fibonacci_Solution1(n) == expected)
printf("Test for %d in solution1 passed.\n", n);
else
printf("Test for %d in solution1 failed.\n", n);
if (Fibonacci_Solution2(n) == expected)
printf("Test for %d in solution2 passed.\n", n);
else
printf("Test for %d in solution2 failed.\n", n);
if (Fibonacci_Solution3(n) == expected)
printf("Test for %d in solution3 passed.\n", n);
else
printf("Test for %d in solution3 failed.\n", n);
}
int main()
{
Test(0, 0);
Test(1, 1);
Test(2, 1);
Test(3, 2);
Test(4, 3);
Test(5, 5);
Test(6, 8);
Test(7, 13);
Test(8, 21);
Test(9, 34);
Test(10, 55);
Test(40, 102334155);
system("pause");
return 0;
}
Test for 0 in solution1 passed.
Test for 0 in solution2 passed.
Test for 0 in solution3 passed.
Test for 1 in solution1 passed.
Test for 1 in solution2 passed.
Test for 1 in solution3 passed.
Test for 2 in solution1 passed.
Test for 2 in solution2 passed.
Test for 2 in solution3 passed.
Test for 3 in solution1 passed.
Test for 3 in solution2 passed.
Test for 3 in solution3 passed.
Test for 4 in solution1 passed.
Test for 4 in solution2 passed.
Test for 4 in solution3 passed.
Test for 5 in solution1 passed.
Test for 5 in solution2 passed.
Test for 5 in solution3 passed.
Test for 6 in solution1 passed.
Test for 6 in solution2 passed.
Test for 6 in solution3 passed.
Test for 7 in solution1 passed.
Test for 7 in solution2 passed.
Test for 7 in solution3 passed.
Test for 8 in solution1 passed.
Test for 8 in solution2 passed.
Test for 8 in solution3 passed.
Test for 9 in solution1 passed.
Test for 9 in solution2 passed.
Test for 9 in solution3 passed.
Test for 10 in solution1 passed.
Test for 10 in solution2 passed.
Test for 10 in solution3 passed.
Test for 40 in solution1 passed.
Test for 40 in solution2 passed.
Test for 40 in solution3 passed.
请按任意键继续. . .