【算法设计zxd】第一章 算法基础 4.设计工具【三角矩阵,】
目錄
1. 循環設計
(1) 設計思維
自底向上的設計(Down - Top Design)
自頂向下的設計(Top-Down Design)
(2)挖掘內在規律構建計算模型
【例1-3】設計算法,輸出一個n×n的三角矩陣,如圖所示規律。
? 問題分析:
計算模型:?
?算法設計與描述:
?算法分析:
算法實現:
(3)改進計算模型提高運算效率
【例1-4】?
?問題分析 ? ? ?
計算模型
算法設計與描述 ? ? ?
算法實現:
2. 遞歸設計
遞歸設計的步驟:
【1-5】運用遞歸方式設計求解斐波那契數列(Fibonacci sequence)的第n項的值
計算模型
算法分析
?3.循環與遞歸的比較
【例1-5】任意給定十進制數:(1)從低位到高位逐位輸出各位數字; (2) 從高位到低位逐位輸出各位數字。
問題分析
算法實現
?
【例1-6】求從n個自然數(1,2,3,…, n)中取出r個數的所有組合。
?計算模型:1)循環算法:
2)遞歸
?算法實現
【1-7】找出n個自然數(1,2,3,…, n)中取出r個數的所有組合。
算法分析
算法設計與描述
?比較總結:
1. 循環設計
(1) 設計思維
自底向上的設計(Down - Top Design)
先找出某個問題的子問題或若干特殊問題,
以定性、定量的方式去描述和解決這些子問題,
然后,逐步合并子問題的解,最后得到大問題的解。
核心本質:合并
自頂向下的設計(Top-Down Design)
將復雜的大問題分解為相對簡單的小問題,
找出每個問題的關鍵、重點所在,
然后用精確的思維定性、定量地去描述問題和解決問題。
核心本質:分解。
例如:歸并算法:自頂向下拆,自底向上合并
(2)挖掘內在規律構建計算模型
挖掘問題的內在規律,進行抽象并構建計算模型
交通指揮燈:數據構造
三角矩陣:運算規律
運算規律:一般找下標對應規律 最快
【例1-3】設計算法,輸出一個n×n的三角矩陣,如圖所示規律。
行列參與運算(下標)
? 問題分析:
問題:要找到按斜行訪問與按矩陣訪問之間的映射關系?
計算模型:
?算法設計與描述:
輸入:矩陣行列值n
輸出:按斜行元素值為連續整數的三角矩陣
?算法分析:
算法主體語句執行次數為:
?其中,L代表斜行,j代表列。
【其實是每一個元素都進行操作,且只進行一次。所以執行次數=元素個數】
【第一斜行n 第二斜行......】
算法實現:
#include<stdio.h>int main()
{// 輸入 int n,k=1;int a[100][100];printf("請輸入n值:");scanf("%d",&n);for(int L=0;L<n;L++)//L是斜行 {for(int j=0;j<n-L ;j++){a[L+j][j] = k++ ;}}//輸出for(int i=0;i<n;i++){for(int j=0;j<=i;j++){printf("%5d",a[i][j]);}printf("\n");} return 0;
}
思考題:n=5*5?
代碼:
#include<iostream>
using namespace std;int main()
{int n=5*5;int k=0;int a[n][n];for (int i=0;i<n;i++){for(int j=0;j<n-i;j++){a[i+j][j]=k++;}}for(int i=0;i<n;i++){for(int j=0;j<=i;j++)//注意這里是<= {cout<<a[i][j]<<" ";}cout<<endl;}return 0;
}
結果:
?
0 0 1
0 1 2
0 2 3
0 3 4
1 0 5
1 1 6
1 2 7
2 0 8
2 1 9
3 0 10
1
5 2
8 6 3
10 9 7 4
(3)改進計算模型提高運算效率
【例1-4】求1/1!-1/3!+1/5!-1/7!+…+(-1)n+1/(2*n-1)!
① 問題分析? ? ? (運算過濾)
迭代方法是在累乘的基礎上實現累加
②計算模型
?中間項
③算法設計與描述 ? ? ?
|
依據式(4-1)設計的算法EA |
依據式(4-2)設計的算法EA_G |
||
|
輸入? |
計算范圍n |
||
|
輸出 |
累加結果S |
||
|
算法 描述 |
step?1:?讀入n,令S=T=1、i=3、j=1,n=2*n-1 step?2:?判斷i<=n,成立T=1轉step3,?否則進入step?6 step?3:?判斷j<=i,成立轉step?4,?否則進入step5 step?4:?執行T=T*j,?j=j+1;?轉step?3; step?5:?計算T的符號; step?6:?S=S+1/T;?i=i+2;?轉step?2; step?7:?輸出S,運算結束。 |
step?1:?讀入n,令S=T=1、i=3,n=2*n-1 step?2:?判斷i<=n,成立轉step3,?否則進入step?5 step?3:?T=(-1)*T*(i-1)*i; step?4:?S=S+1/T;?i=i+2;?轉step?2; step?5:?輸出S,運算結束。 |
|
| 3 4是內層循環 | 少去內層循環 | ||
④算法分析(缺)
⑤算法實現:
EA
// EA
#include<stdio.h>
int main()
{float s=1.0f,t;int n,count=2;//項數printf("請輸入計算項數:");scanf("%d",&n);for(int i=3;i<=2*n-1;i+=2){t=1.0f;//每次都重新算for(int j=2;j<=i;j++)//分母{t=t*j; }for(int j=1;j<=count+1;j++){t=-t;}s=s+ 1/t;count++;}printf("s=%f\n",s);
}
?EA_G?
// EA _ G
#include<stdio.h>
int main()
{float s=1.0f,t=1.0f;int n;printf("請輸入計算項數:");scanf("%d",&n);for(int i=3;i<=2*n-1;i+=2){t= -t*(i-1)*i;//計算分母 s=s+ 1/t;}printf("s=%f\n",s);
}
⑥測試
⑦結果整理與文件編制
2. 遞歸設計
定義:一個過程或函數在定義中直接或間接調用自身的一種方法。
設計關鍵:找出遞歸關系(方程)和遞歸終止(邊界)條件。遞歸關系就是使問題向邊界條件轉化的規則。
遞歸設計的步驟:
(1) 分析問題找到遞歸關系:找出大規模問題與小規模問題的關系,以便通過遞歸使問題規模變小。(收斂的)
(2)設置終止條件控制遞歸:通過停止條件的設置,找出可解的最小規模問題。
(3)設計函數確定數據傳遞方式。
【1-5】斐波那契的第n項 遞歸
運用遞歸方式設計求解斐波那契數列(Fibonacci sequence)的第n項的值
計算模型
遞歸的終止條件和遞歸方程,如下:
其中,式(5-2)是遞歸方程,式(5-1)是終止條件。
算法分析
?依據計算模型,容易得知,求第n項的值需要計算n-2次,所以,主體算法計算次數約為f(n)=n-2
斐波那契:算法實現 C
#include<stdio.h> int fcc(int n)
{int t;if(n==1|n==2)return 1;else return fcc(n-1)+fcc(n-2);
}
int main()
{int n;printf("input n:");scanf("%d",&n);printf("No.%d value of Fibonacci sequence is %d\n ",n,fcc(n));return 0;
}
?3.循環與遞歸的比較
每個迭代算法原則上總可以轉換成與它等價的遞歸算法;
反之則不然,
就是說不是每個遞歸算法都可以轉換成與它等價的循環結構算法。
?
【例1-5】任意給定十進制數:(1)從低位到高位逐位輸出各位數字; (2) 從高位到低位逐位輸出各位數字。
問題分析
這是一個較為簡單的問題,我們將從實現的角度來比較兩者對于問題的適應性。
算法實現
(1)從低位到高位:效率實際一樣
(2)從高位到低位:循環首先需要確定位數,遞歸——聯系到樹的先根遍歷和中 后
改變要求,遞歸變化可能極小
思考題:嘗試總結 遞歸與循環 的優缺點?
思考題:用遞歸求出斐波那契數列 去除重復計算
#include<iostream>
using namespace std;
//遞歸
int fb(int i)
{if(i==1||i==2)return 1;else return fb(i-1)+fb(i-2);
}
//時間復雜度O(2^n)
//空間復雜度O(1) //數組,去重,用空間換時間
int a[40];
int fib(int n)
{a[0]=0;a[1]=1;for(int i=2;i<=n;i++){a[i]=a[i-1]+a[i-2];}return a[n];
}
//時間O(n)
//空間O(n) //動態規劃
int fibdp(int n)
{int f=0;int fp=1;while(n--){fp=fp+f;//規則 f=fp-f;//恢復fplus }return f;
}
//時間O(n)
//空間O(1)
int main()
{cout<<fb(12)<<endl;return 0;
}
代碼:
?
#include<iostream>
using namespace std;void gaocir(int n)
{int b[20];int i=0;while(n){b[i]=n%10;n=n/10;i++;}while(i--){cout<<" "<<b[i]''}
}
void gaodg(int n)
{if(n<10)cout<<" "<<n;else{gaodg(n/10);cout<<" "<<n%10;}
}
void dicir(int n)
{cout<<"低位開始 循環";while(n){cout<<" "<<n%10;n=n/10;}
}
void didg(int n)
{
// cout<<"低位開始 遞歸";if(n<10)cout<<" "<<n;else { cout<<" "<<n%10;didg(n/10);}
}
int main()
{int n=12345;return 0;
}
【例1-6】求從n個自然數(1,2,3,…, n)中取出r個數的所有組合。
問題分析
?計算模型:
1)循環算法:
設i代表第i個位置,則 r 個位置上的取值范圍依次為:
?其中, 1 ≤ r ≤ n , 且 r 在循環算法實現時 代表循環嵌套的層數,必須是定值。
2)遞歸
?算法實現
算法分析
算法設計與描述
?比較總結:
|
遞歸 |
循環 |
|
|
程序可讀性 |
易 |
難 |
|
代碼量大小 |
小 |
大 |
|
時間 |
長 |
短 |
|
占用空間 |
大 |
小 |
|
適用范圍 |
廣 |
窄 |
|
設計難度 |
易 |
難 |
總結
以上是生活随笔為你收集整理的【算法设计zxd】第一章 算法基础 4.设计工具【三角矩阵,】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享10道常考Java面试题及答案
- 下一篇: SQL注入时间盲注