简单迭代运算
**迭代(辗转法)**是一种不断用变量的旧值递推新值的过程
分类
- 精确迭代:杨辉三角、内在移动算法等
- 近似迭代:二分法和牛顿迭代法等
设计方法
- 确定迭代模型
根据问题描述,抽象出当前值和下一个值的迭代关系。这一迭代关系应该最终收敛于所期望的目标。迭代模型时解决迭代问题的关键。
- 控制迭代过程
迭代模型会包含期望的目标,根据这一目标控制迭代的次数,并最终结束算法。迭代过程的控制通常分为两种情况:一种是已知或可以计算出来迭代的次数,这时可以构建一个固定次数的循环来实现对迭代过程的控制。另一种是所需的迭代次数无法确定,需要分析出迭代过程的结束条件,还要考虑有可能得不到目标解(迭代不收敛)的情况,避免出现迭代过程的死循环。
例题
1
【例题1】输出杨辉三角形
问题分析
利用一个n*n的矩阵存储信息。如下

有
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轮
算法设计与描述

算法分析

注:可以进行改进,减少内层循环次数。
【例题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轮
算法设计与描述

算法分析

注:可以进行改进,减少内层循环次数。
【例题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轮
算法设计与描述

算法分析

注:可以进行改进,减少内层循环次数。
【例题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