簡單迭代運算
**迭代(輾轉法)**是一種不斷用變量的舊值遞推新值的過程
分類
- 精確迭代:楊輝三角、內在移動算法等
- 近似迭代:二分法和牛頓迭代法等
設計方法
- 確定迭代模型
根據問題描述,抽象出當前值和下一個值的迭代關係。這一迭代關係應該最終收斂於所期望的目標。迭代模型時解決迭代問題的關鍵。
- 控制迭代過程
迭代模型會包含期望的目標,根據這一目標控制迭代的次數,並最終結束算法。迭代過程的控制通常分爲兩種情況:一種是已知或可以計算出來迭代的次數,這時可以構建一個固定次數的循環來實現對迭代過程的控制。另一種是所需的迭代次數無法確定,需要分析出迭代過程的結束條件,還要考慮有可能得不到目標解(迭代不收斂)的情況,避免出現迭代過程的死循環。
例題
1
【例題1】輸出楊輝三角形
問題分析
利用一個n*n的矩陣存儲信息。如下
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
有
ai,j=ai−1,j−1+ai−1,j
計算模型
⎩⎨⎧ai,i=1ai,0=1ai,j=ai−1,j−1+ai−1,ji>1且1≤j<i
算法設計與描述
輸入:
n
輸出:楊輝三角
step1: 輸入
n,定義一個n
×n的存儲矩陣
a
step2: 令
a0,0=1,a1,0=1,a1,1=1, 定義
i=2
step3: 令
ai,0=1,ai,i=1,定義
j=1
step4: 令
ai,j=ai−1,j−1+ai−1,j,j=j+1,若
j<i,轉step4
step5: 令
i=i+1,若
i<n 轉step3
step6: 打印輸出矩陣
a,算法結束
算法分析
- 輸入
n,規模爲
n
- 核心操作:
ai,j=ai−1,j−1+ai−1,j
- 得出
T(n)=∑i=2n−1(2+∑j=1i−11)+3=Θ(n2)
2
【例題2】內存移動問題:數組中有n個數據,要將它們順序循環向後移k位,即前面的元素向後(右)移k位,後面的元素則循環向前移k位,例:0、1、2、3、4、5循環移3位後爲: 3、4、5、0、1、2。考慮到n會很大,不允許用2*n及以上個空間來完成此題。
問題分析
設原數列爲
a[n],移動k次。
- 建立一個數列
b[n],令
b[(k+i)modn]=a[i],i∈[0,n−1]
此時,時間複雜度爲
O(n),空間複雜度爲
O(2n),不符合題目要求。
- 建立臨時變量
tmp,令
tmp=a[n−1],然後從
a[n−2]開始所有位右移一位,最後,令
a[0]=tmp,實現右移一位,循環實現右移k位。
此時,時間複雜度爲
O(k×n),空間複雜度爲
O(n+1)=O(n)
- 如果按照2的方法將元素直接移動至指定位置,那麼時間複雜度爲
O(n),空間複雜度爲
O(n)。
如:n = 6,k = 3的情況,將
a[0]→a[3],
a[3]→a[0];
a[1]→a[4],
a[4]→a[1],
a[2]→a[5],
a[5]→a[2],共需要移動3輪,每輪移動元素個數爲2。
不難發現,此時
移動輪數=gcd(n,k)
下面給出證明:
令
gcb(n,k)=q,每輪最少移動元素個數爲
r
從而有:
n=q×n1,k=q×n2n1,n2∈Z 且
gcb(n1,n2)=1
由每輪第一次移動的元素要和最後一次移動到的元素相同可得:
(k×r)modn=0
從而推出:
(n2×r)modn1=0
由
gcb(n1,n2)=1可得:
gcb(n1,r)=n1
r 爲每輪最小移動次數,取
n1,此時移動輪數爲
n/r=q
下文主要講述第三種方法
計算模型
- 求出最大公約數,由歐幾里得
⎩⎪⎪⎨⎪⎪⎧a,b=b,ar=amodbgcd(a,b)=gcb(b,r)gcd(a,b)=b若b>ar=0r=0初始化進入循環判斷結束
- 令
q=gcb(a,b) [上一步所求出來的], 移動次數:
i=n/q
- 計算元素移動位置:
xi=(xm+i×k)modn0≤i<n/q0≤xm<q
說明:初始元素爲
xm,第
i次移動實現
a[xi−1]→a[xi] ,共移動
q輪
算法設計與描述
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
算法分析
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
注:可以進行改進,減少內層循環次數。
【例題3】求n!(n<=100)
問題分析
int整數表示的範圍爲:-2147483648 —— -2147483647,顯然不能直接處理規模爲100的階乘計算。所以需要藉助一個int型數組a,設定每個元素存儲6位整數,由式子
log(n!)=Θ(nlogn)可得數組中約需要34個元素。
計算方法:模擬豎式乘法
計算模型
設存儲大數結果的數組爲
a[m],
m=n(logn)/6
初始化
a[0]=1,a[i]=
a[xi−1]→a[xi] ,共移動
q輪
算法設計與描述
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
算法分析
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
注:可以進行改進,減少內層循環次數。
【例題3】求n!(n<=100)
問題分析
int整數表示的範圍爲:-2147483648 —— -2147483647,顯然不能直接處理規模爲100的階乘計算。所以需要藉助一個int型數組a,設定每個元素存儲6位整數,由式子
log(n!)=Θ(nlogn)可得數組中約需要34個元素。
計算方法:模擬豎式乘法
計算模型
設存儲大數結果的數組爲
a[m],
m=n(logn)/6
初始化
a[0]=1,a[i]=0(i=0)
] ,共移動
q輪
算法設計與描述
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
算法分析
![在這裏插入圖片描述](http://static.javashuo.com/static/loading.gif)
注:可以進行改進,減少內層循環次數。
【例題3】求n!(n<=100)
問題分析
int整數表示的範圍爲:-2147483648 —— -2147483647,顯然不能直接處理規模爲100的階乘計算。所以需要藉助一個int型數組a,設定每個元素存儲6位整數,由式子
log(n!)=Θ(nlogn)可得數組中約需要34個元素。
計算方法:模擬豎式乘法
計算模型
設存儲大數結果的數組爲
a[m],
m=n(logn)/6
初始化
a[0]=1,a[i]=0(i=0)
a[m],
m