斐波那契改进:
(一)定义:
这个问题时这样定义的:
0 (x <= 0)
f(x) = 1 (x == 1)
f(x - 1) + f(x - 2) (x > 1)
看到这个递推公式后,我们很容易可以写出如下的代码:
(二)方法一:递归:
/*经典的斐波那契数列的递归解法,而且每个人都知道这种方法效率很低*/
ll DutFibonacci_1(int n)
{
if (n <= 0)
return 0;
else if (n == 1)
return 1;
else
return DutFibonacci_1(n - 1) + DutFibonacci_1(n - 2);
}
缺陷:当n较大时,需要等待很长时间,利用栈的效率很低。
(三)方法二:
ll DutFibonacci_2(int n)
{
if (n <= 0)
return 0;
else if (n == 1)
return 1;
ll one = 0;
ll two = 1;
ll result ;
/*非递归解法也很简单,利用两个中间数,计算“曾经”出现的值就可以了*/
for (int i = 2; i <= n; ++i)
{
result = one + two;
one=two;
two = result;
}
return result;
}
----------------------------------------------
Linux C实现 斐波那契数列,输出第100个数,大概是10的21次方。没有uint128_t这样的数据结构,给出原理,注释,实现。
#include <stdio.h>
#include <string.h>
#define MAX_DIGITS 30 // 足够存 10^21
/**
* 大整数加法:c = a + b; (低位在前存储,如123存储为[3,2,1,0,...])
* a, b 是输入,c 是输出
* 低位在前存储:数组[0] = 个位,[1] = 十位,依此类推
*/
void bigIntAdd(int *a, int *b, int *c) {
int carry = 0; // 进位
// 先把 c 全部清 0,避免旧数据干扰
memset(c, 0, MAX_DIGITS * sizeof(int));
// 逐位相加
for (int i = 0; i < MAX_DIGITS; i++) {
int sum = a[i] + b[i] + carry; // 当前位总和
c[i] = sum % 10; // 当前位只保留个位数
carry = sum / 10; // 进位留给下一位
}
}
/**
* 打印大整数(低位在前,需要逆序输出)
*/
void printBigInt(int *num) {
// 找到最高有效位
int start = MAX_DIGITS - 1;
while (start > 0 && num[start] == 0) {
start--;
}
// 从高位 → 低位输出
for (int i = start; i >= 0; i--) {
printf("%d", num[i]);
}
printf("\n");
}
int main() {
int f1[MAX_DIGITS] = {0}; // F(n-2)
int f2[MAX_DIGITS] = {0}; // F(n-1)
int f3[MAX_DIGITS] = {0}; // F(n) = F(n-1)+F(n-2)
// 初始化前两项:F(1)=1,F(2)=1
f1[0] = 1;
f2[0] = 1;
// 从第 3 项算到第 100 项
for (int i = 3; i <= 100; i++) {
// f3 = f1 + f2
bigIntAdd(f1, f2, f3);
// 迭代更新:
// 下一轮的 f1 = 本轮 f2
// 下一轮的 f2 = 本轮 f3
memcpy(f1, f2, sizeof(f1));
memcpy(f2, f3, sizeof(f2));
}
printf("斐波那契第 100 项:");
printBigInt(f2); // 最后 f2 就是第 100 项
return 0;
}
本文介绍了斐波那契数列的经典递归解法及其存在的效率问题,并提出了一种非递归的方法来提高计算效率。
608

被折叠的 条评论
为什么被折叠?



