輸入一個正整數 n,輸出費波那契數列前 n 項。
定義:F(1)=1, F(2)=1, F(n)=F(n-1)+F(n-2) (n≥3)
#include <stdio.h>
void print_fibonacci(int n) {
if (n <= 0) return;
long long a = 0, b = 1; // 使用 long long 擴大範圍
// 輸出第 1 項
printf("%lld", b);
if (n == 1) { printf("\n"); return; }
// 輸出第 2 到 n 項
for (int i = 2; i <= n; i++) {
long long c = a + b;
a = b;
b = c;
printf(" %lld", b);
}
printf("\n");
}
int main() {
int n;
printf("請輸入項數 n:");
if (scanf("%d", &n) != 1 || n <= 0) {
printf("輸入無效\n");
return 1;
}
print_fibonacci(n);
return 0;
}
請輸入項數 n:10 1 1 2 3 5 8 13 21 34 55
| 型態 | 位元數 | 最大值 | 能容納的最大費波項數 |
|---|---|---|---|
| int | 32 | 2,147,483,647 | F(46) = 1,836,311,903 |
| unsigned int | 32 | 4,294,967,295 | F(47) = 2,971,215,073 |
| long long | 64 | 9,223,372,036,854,775,807 | F(92) = 7,540,113,804,746,346,429 |
| unsigned long long | 64 | 18,446,744,073,709,551,615 | F(93) = 12,200,160,415,121,876,738 |
超過 F(93) 即會溢位 64 位無符號整數。
#include <stdio.h>
#include <string.h>
#define MAX_DIGITS 500 // 支援極大數字
// 高精度加法:num1 += num2 (兩個以字串形式儲存的大數,低位在前)
void big_add(char *num1, const char *num2) {
int carry = 0;
int len1 = strlen(num1);
int len2 = strlen(num2);
int max_len = len1 > len2 ? len1 : len2;
for (int i = 0; i < max_len || carry; i++) {
int d1 = (i < len1) ? num1[i] - '0' : 0;
int d2 = (i < len2) ? num2[i] - '0' : 0;
int sum = d1 + d2 + carry;
if (i < len1) num1[i] = (sum % 10) + '0';
else num1[i] = (sum % 10) + '0';
carry = sum / 10;
}
// 更新長度(隱含在字串結尾)
}
// 列印大數(低位在前需反轉)
void print_big(const char *num) {
int len = strlen(num);
for (int i = len - 1; i >= 0; i--) putchar(num[i]);
}
void fibonacci_big(int n) {
if (n <= 0) return;
char a[MAX_DIGITS] = "0"; // F(0)
char b[MAX_DIGITS] = "1"; // F(1)
char c[MAX_DIGITS];
print_big(b);
if (n == 1) { putchar('\n'); return; }
for (int i = 2; i <= n; i++) {
strcpy(c, a);
big_add(c, b); // c = a + b
strcpy(a, b); // a = b
strcpy(b, c); // b = c
putchar(' ');
print_big(b);
}
putchar('\n');
}
int main() {
int n;
printf("請輸入項數 n(大數版):");
scanf("%d", &n);
fibonacci_big(n);
return 0;
}
請輸入項數 n(大數版):100 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 20365011074 32951280099 53316291173 86267571272 139583862445 225851433717 365435296162 591286729879 956722026041 1548008755920 2504730781961 4052739537881 6557470319842 10610209857723 17167680177565 27777890035288 44945570212853 72723460248141 117669030460994 190392490709135 308061521170129 498454011879264 806515533049393 1304969544928657 2111485077978050 3416454622906707 5527939700884757 8944394323791464 14472334024676221 23416728348467685 37889062373143906 61305790721611591 99194853094755497 160500643816367088 259695496911122585 420196140727489673 679891637638612258 1100087778365702931 1779979416004315189 2880067194370018120 4660046610374331309 7540113804744349429 12200160415121680738 19740274219866030167 31940434634987710895 51680708854853741062 83621143489841451957 135301852344695193019 218922995834536644976 354224848179231837995 573147844013768482971 927372692193000320966 1500520536206768803937 2427893228399769124903 3928413764606537928840 6356306993006307053743 10284720757612844982583 16641027750619152036323 26925748508231997018906 43566776258851149055229 70492524767083146074135 114059301025934295129364 184551825793017441203499 298611126818951736332863 483162952611969177536362 781774079430920913869225 1264937032042890091405587 2046711111473811005274812 3311648143516701096680399
// 指數級時間複雜度 O(2^n),極度低效,僅供理解遞迴概念
long long fib_recursive(int n) {
if (n <= 2) return 1;
return fib_recursive(n - 1) + fib_recursive(n - 2);
}
// 記憶化遞迴(DP 優化)O(n) 時間、O(n) 空間
long long memo[100] = {0};
long long fib_memo(int n) {
if (n <= 2) return 1;
if (memo[n]) return memo[n];
return memo[n] = fib_memo(n - 1) + fib_memo(n - 2);
}
利用矩陣乘法性質:[F(n+1) F(n)] = [F(n) F(n-1)] × [[1,1],[1,0]]
typedef struct { long long m[2][2]; } Matrix;
Matrix multiply(Matrix a, Matrix b) {
Matrix res = {{{0,0},{0,0}}};
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
res.m[i][j] += a.m[i][k] * b.m[k][j];
return res;
}
Matrix power(Matrix base, int exp) {
Matrix res = {{{1,0},{0,1}}}; // 單位矩陣
while (exp > 0) {
if (exp & 1) res = multiply(res, base);
base = multiply(base, base);
exp >>= 1;
}
return res;
}
long long fib_matrix(int n) {
if (n <= 2) return 1;
Matrix base = {{{1,1},{1,0}}};
Matrix res = power(base, n - 2);
return res.m[0][0] + res.m[0][1];
}
| 場景 | 推薦方法 | 理由 |
|---|---|---|
| 教學/小 n (≤92) | 迭代法 + long long | 簡單、高效、無溢位 |
| 大 n 需精確值 | 高精度陣列/字串模擬 | 突破硬體限制、任意精度 |
| 競賽求單項 F(n) 模 M | 矩陣快速冪/快速倍增 | O(log n) 極快、適合取模 |
| 理解遞迴概念 | 遞迴/記憶化遞迴 | 代碼直觀、易驗證數學定義 |
費波那契數列看似簡單,實則蘊含豐富的演算法思想:遞迴、動態規劃、矩陣乘法、高精度運算。掌握多種解法,才能應對不同場景需求。