迭代法 详解

迭代法(iteration)也称辗转法,是一种不断用变量的旧值递推出新值的解决问题的方法,迭代算法一般用于数值计算。累加,累乘都是迭代算法的基础应用。

利用迭代法解题的步骤:

1)确定迭代模型

   根据问题描述,分析出前一个(或几个)值与下一个值的迭代关系数学模型。

2)建立迭代关系式

  递推数学模型一般是带下标的字母,算法设计中要将其转化为“循环不变式”—-迭代关系式,迭代关系式就是一个直接或间接地不断由旧值递推出新值的表达式,存储新值的变量称为迭代变量。

3)对迭代过程进行控制。

  确定在什么时候结束迭代过程。

迭代过程是通过小规模问题的解逐步求解大规模问题的解,表面上看正好与递归相反,但也找到了大规模问题与小规模问题的关系。

本节的例子是用迭代完成的,也都可以用递归完成。相信尝试后,定能体会到递归的简便之处。

1,递推法 (recursion)是迭代算法的最基本表现形式。一般来讲,一种简单的递推方法,就是从小规模的问题解出大规模问题的一种方法,也称其为“正推“。如”累加“。

兔子繁殖问题: 一对兔子从出生后第三个月开始,每月生一对兔子,小兔子每到第三个月有开始生兔子,问一年中每个月各有多少兔子?

我们通常用的迭代:

print(a,b)

for(i=1;i<=10;i++)

 {

    c=a+b;

  print(c);

  a=b;

  b=c;

}

另一种构造不变式的方法:

1  2    3    4    5    6    7    8

a  b  c=a+b   a=b+c  b=a+c   c=a+b

这样,一次循环其实是递推了三步,循环次数就要减少了。

#include<stdio.h>

int main()
{
    
    int i,a=1,b=1;
    int c;
    printf("%d %d ",a,b);
    for(i=1;i<=4;i++)
    {
        c=a+b;
        a=b+c;
        b=c+a;
        printf("%d %d  %d  ",c,a,b); //注意输出顺序是c,a,b
    }
}

上面输出的共2+3*4=14项,这样的算法不太完美。

另一种思路,

1     2   3    4    5

a  b  a=a+b  b=a+b   a=a+b

#include<stdio.h>

int main()
{
    
    int i,a=1,b=1;
    int c;
    printf("%d %d ",a,b);
    for(i=1;i<=5;i++)
    {
        a=a+b;
        b=a+b;
        printf("%d %d  ",a,b);
    }
}

2.倒推法(inverted recursion)对某些特殊问题所采用的违反通常习惯的,从后向前推解问题的方法。

猴子吃桃问题: 一只小猴子摘了若干桃子,每天吃现有的桃的一半多一个,到第十天时就只有一个桃子了,求原有多少个桃?

数学模型

a10=1,a9=(1+a10)*2 ,a8=(1+a9)*2…

递推公式为:

ai=(1+a(i+1) )*2 ; i=9 ,8  .. .1

由于每一天的桃子树只依赖前一天的桃子数,所以只用一个迭代变量代表桃子数就可以了。

int main()
{
    int i,a;
    a=1;
    for(i=9;i>=1;i--)
        a=(a+1)*2;
    printf("%d",a);
}

输出如图所示的杨辉三角形(限定用一个一维数组完成)

      1                           1

     1    1                        1  1

1         2   1                     1        2      1  杨辉三角存储格式

#include<iostream>
using namespace std;

int main()
{

    int n,i,j,a[100];
    cin>>n;
    cout<<1<<endl;
    a[1]=a[2]=1;
    cout<<a[1]<<ends<<a[2]<<endl;
    for(i=3;i<=n;i++)
    {
        a[1]=a[i]=1;
        for(j=i-1;j>1;j--)
             a[j]=a[j]+a[j-1];
        for(j=1;j<=i;j++)
            cout<<a[j]<<ends;
        cout<<endl;
    }
}

若求n层的杨辉三角,则数组最多存储n个数据(第n层有n个数据)就可以了。

第i层有i列需要求解i个数据,若从第一列向后计算,求第i行时,由于用一个一维数组存储,每求出一个数将覆盖第i-1行对应列存储的

值,这将导致下一个数无法计算,而从第i个元素倒着向前计算就能正常进行,则可避免这种情况出现。

a[j]=a[j]+a[j-1]; j=i-1,i-2, … 2

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注