250 likes | 359 Views
第 2 章 陣列與排序 (Sorting). 2.1 第 2000 個 Fibonacci number. 於 1.3 節中介紹了如何以 C 程式利用迴圈與遞迴函數來求第 n 個費氏數, 其中 n 小於 47. 對於大於 46 的 費氏數 , 例如我們需用需用 1000 位數等 , 方能處理如第 2000 個費氏數. 因此 , 我們需用陣列來處理很大的數 , 我們可以用一個 byte 來儲存一位數 0, 1, …, 9. 欲 儲存 1000 位數的數 , 則需 1000 個 bytes 的陣列 . 其宣告方式如下 :.
E N D
第 2 章 陣列與排序(Sorting) 2.1 第 2000 個 Fibonacci number 於 1.3 節中介紹了如何以 C 程式利用迴圈與遞迴函數來求第 n 個費氏數, 其中 n 小於47. 對於大於 46 的費氏數, 例如我們需用需用1000 位數等, 方能處理如第 2000 個費氏數. 因此, 我們需用陣列來處理很大的數, 我們可以用一個 byte 來儲存一位數0, 1, …, 9. 欲儲存 1000位數的數, 則需 1000 個 bytes 的陣列. 其宣告方式如下: int n; // n 表示有效位數 char a[1000];
因此, 我們可利用n 與陣列 a 表一非負整數. 如果 n = 12, a[1]=1, a[2]=2, a[3]=3, a[4]=4, a[5]=5, a[6]=6, a[7]=7, a[8]=8, a[9]=9, a[10]=0, a[11]=1, a[12]=2, 其餘的 a 值為 0, 則該陣列代表一整數 210987654321. 我們暫以 <n,a>=210987654321 表之. 兩數相加就如同一般算數加法, 需要由個位數加起, 並考慮進位問題. 設有兩數 <n1, a1> = 79, <n2, a2> = 958, 其和為 <n3, a3> = 1037. 變數與陣列 n1, a1, n2, a2, n3 與 a3 的內容分別為 n1 = 2, a1[1] = 9, a1[2] = 7, n2 = 3, a2[1] = 8, a2[2] = 5, a2[3] = 9, n3 = 4, a3[1] = 7, a3[2] = 3, a3[3] = 0, a3[4] = 1.
一個相當沒有模組架構的程式如下: #include <stdio.h> #define MAXSIZE 1001 void main() { int n1, n2, n3; char a1[MAXSIZE], a2[MAXSIZE], a3[MAXSIZE]; int i, j, n, carry; printf("Supply a number for Finbonacci number: "); scanf("%d", &n); for(i=0; i<MAXSIZE; i++) { a1[i]=a2[i]=a3[i]=0; } n1=n2=n3=1;
// result is stored in a3[] if(n<0) printf("The input %d is negative!\n", n); else if(n <= 1) printf("The %dth Fibonacci number is %d.\n", n, n); else { a2[1]=1; for(i=2; i<=n; i++) { // a3 = a1 + a2 carry = 0; n3 = n2; for(j=1; j<=n2; j++) { a3[j] = a1[j] + a2[j] + carry;
if(a3[j] >=10 ) { a3[j]= a3[j] - 10; carry = 1; } else carry = 0; } if(carry) { n3 = n3 + 1; a3[n3]=carry; } // a1 = a2 n1 = n2; for(j=1; j<=n2; j++) a1[j]=a2[j]; // a2 = a3 n2 = n3; for(j=1; j<=n3; j++) a2[j]=a3[j]; }// for loop
// print out the Fibonacci number printf("The %dth Fibonacci number is:\n", n); for(j=n3; j>=1; j--) { printf("%d", a3[j]); if( (n3-j+1)%50==0) printf("\n"); } printf("\nIt has %d digits.\n", n3); }// else }
我們可以利用 C 程式的 struct 架構, 來設計一個具有抽象資料型態的整數, 其架構如下 : (1)抽象資料型態 struct longint 的宣告: struct longint{ int n, char d[MAXSIZE];}; (2)抽象資料型態 struct longint變數與指標的定義與宣告: struct longint a1, a2, a3, *pa; 變數 a1, a2 與 a3 皆有 2 個分量: n 與 d. 變數 pa 為一指標.
(2) 變數的使用: 設定 a1 等於 0. a1.n=1; for (i = 0; i<MAXSIZE; i++) a1.d[i]= 0; (3) 指標的使用: 設定 a2 等於 1. pa = &a2; pa->n=1; for (i = 0; i<MAXSIZE; i++) pa->d[i]= 0; pa->d[1]= 1;
一個具有抽象資料型態 struct longint 的程式如下: #include <stdio.h> #define MAXSIZE 1001 struct longint{ int n; char d[MAXSIZE];}; void main() { struct longint a1, a2, a3; int i, j, n, carry; printf("Supply a number for Finbonacci number: "); scanf("%d", &n); for(i=0; i<MAXSIZE; i++) { a1.d[i]=a2.d[i]=a3.d[i]=0;} a1.n=a2.n=a3.n=1;
// result is stored in a3 if(n<0) printf("The input %d is negative!\n", n); else if(n <= 1) printf("The %dth Fibonacci number is %d.\n", n, n); else { a2.d[1]=1; for(i=2; i<=n; i++) { // a3 = a1 + a2 carry = 0; a3.n = a2.n; for(j=1; j<=a3.n; j++) { a3.d[j] = a1.d[j] + a2.d[j] + carry;
if(a3.d[j] >=10 ) { a3.d[j]= a3.d[j] - 10; carry = 1;} else carry = 0; } if(carry) { a3.n = a3.n + 1; a3.d[a3.n]=carry; } a1 = a2; a2 = a3; }// for loop
// print out the Fibonacci number printf("The %dth Fibonacci number is:\n", n); for(j=a3.n; j>=1; j--) { printf("%d", a3.d[j]); if( (a3.n-j+1)%50==0) printf("\n"); } printf("\nIt has %d digits.\n", a3.n); } }
一個較有模組化 的程式如下: #include <stdio.h> #define MAXSIZE 1001 struct longint{ int n; char d[MAXSIZE];}; void setZero(struct longint *a) { int i; for(i=0; i<MAXSIZE; i++) { a->d[i] =0;} a->n=1; }
void setOne(struct longint *a) { int i; for(i=0; i<MAXSIZE; i++) { a->d[i] =0;} a->n=1; a->d[1]=1; }
struct longint add(struct longint a, struct longint b) { int j, carry; struct longint c; setZero(&c); if(b.n >= a.n) c.n = b.n; else c.n = a.n; carry = 0; for(j=1; j<=c.n; j++) { c.d[j] = a.d[j] + b.d[j] + carry; if(c.d[j] >=10 ){ c.d[j]= c.d[j] - 10; carry = 1;} else carry = 0; } if(carry){ c.n = c.n + 1; c.d[c.n]=carry; } return c; }
void printOutLongint(struct longint a) { int j; for(j=a.n; j>=1; j--) { printf("%d", a.d[j]); if( (a.n-j+1)%50==0) printf("\n"); } printf("\n"); }
void main() { struct longint a1, a2, a3; int i, n; printf("Supply a number for Finbonacci number: "); scanf("%d", &n); setZero(&a1); setOne(&a2); setZero(&a3); if(n<0) printf("The input %d is negative!\n", n); else if(n <= 1) printf("The %dth Fibonacci number is %d.\n", n, n);
else { for(i=2; i<=n; i++) { a3 = add(a1, a2); a1 = a2; a2 = a3; } printf("The %dth Fibonacci number is:\n", n); printOutLongint(a3); printf("\nIt has %d digits.\n", a3.n); } }
一個 C++ 的程式如下: #include <iostream.h> #define MAXSIZE 1001 class longint{ private: int n; char d[MAXSIZE]; public: longint(){ for(int i=0; i<MAXSIZE; i++) d[i] =0; n=1;} ~longint(){}
public: void setOne() { for(int i=0; i<MAXSIZE; i++) d[i] =0; n=1; d[1]=1; } int getDigits() { return n; }
void add(longint a, longint b) { int j, carry; if(b.n >= a.n) n = b.n; else n = a.n; carry = 0; for(j=1; j<= n; j++) { d[j] = a.d[j] + b.d[j] + carry; if(d[j] >=10 ){ d[j]= d[j] - 10; carry = 1;} else carry = 0; } if(carry){ n = n + 1; d[n]=carry; } }
void setEqual(longint a) { int j; n = a.n; for(j=1; j<= n; j++) { d[j] = a.d[j]; } } void printOutLongint( ) { for(int j = n; j>=1; j--) { cout<<(int)d[j]; if( (n-j+1)%50==0) cout<<endl; } cout<<endl; }};
void main() { longint a1, a2, a3; int i, n; cout<<“Supply a number for Finbonacci number: “; cin >> n; if(n<0) cout<<“The input “<<n<<“ is negative! “<<endl; else if(n <= 1) cout<<“The “<<n<<“th Fibonacci number is “<<n<<endl;
else { a2.setOne(); for(i=2; i<=n; i++) { a3.add(a1, a2); a1.setEqual(a2); a2.setEqual(a3); } cout<<“The “<<n<<“th Fibonacci number is:”<<endl; a3.printOutLongint(); cout<<“It has “<<a3.getDigits()<<“ digits. “<<endl; } }
問題: 如何列印出 10000! ? 已知 10000! <= (10^ 4)^10000 = 10 ^ 40000 因此 10000! 小於 4 萬位數. 我們亦可利用 struct longint 來列印出 10000!. 問題: 為了能增加位數,每個字元都可視為 2 位數,也就是說,我們將字串視為 100 進位,而不是十進位。試將前面的程式修改為 100 進位的程式。