编程能力提高-----循环的设计技巧(for、while)

来源:互联网 发布:小狐仙软件功能 编辑:程序博客网 时间:2024/06/05 03:04

  循环是程序设计中接触最多code。在进行数值计算的时候,循环往往是用来做累加或累乘的。累加和累乘都有通用的数学模型:Sn=Sn1+AnTn=Tn1An。根据这两个数学模型,很容易构造出循环体。


例1:实现一个函数,求1+2+3+…+100的和。

int sum (int n){    int s=0;    for(int i=1;i<=n;i++)        s=s+i;               //累和,超级简单。    return s;}

例2:设计求 n!n为正整数)的算法。

long long int fun (int n){    long long int f=1;    for(int i=1;i<=n;i++)        f=f*i;               //累积,超级简单。    return f;}

但在编程中,问题往往既涉及累加式又涉及到累乘式。如下面这个题目:

例3:设计求1/1!1/3!+1/5!1/7!+...+(1)n+1/(2n1)!n为正整数)的算法。

分析问题:
首先,数学模型为:Sn=Sn1+(1)n+1/(2n1)!
其次,累加的对象是一个累积的结果。
所以,初学者很容易想到利用二重循环实现该算法。

int main(){    int i,j,n,sign=1;      //i、j为循环控制变量,n为问题规模    float s=1,t=1;         //s累和,t累积    scanf("%d",&n);    for(i=2;i<=n;i++)    {        t=1;        for(j=1;j<=2*i-1;j++)            t*=j;        sign=1;        for(j=1;j<=i+1;j++)            sign=sign*(-1);        s=s+sign/t;    }    printf("sum=%d",s);}

  对以上算法分析,是正确的,但是时间复杂度是O(n2),效率低。因为在内循环中求出7!后,再去求9!时,没必要再从1去累乘到9,只需充分利用前一次的结果,用7!89即可求得9!。所以数学模型修正为:An=An11/((2n2)(2n1))。另外sign=sign(1);总共也要执行n(n1)/2次乘法操作,这也是没必要的,用赋值运算效率更高,sign=sign;

数学模型2:Sn=Sn1+(1)n+1AnAn=An11/((2n2)(2n1))

int main(){    int i,n,sign=1;        //i为循环控制变量,n为问题规模    float s=1,t=1;         //s累和,t累积    scanf("%d",&n);    for(i=2;i<=n;i++)    {        sign=-sign;        t=t*(2*i-2)*(2*i-1);                s=s+sign/t;    }    printf("sum=%d",s);}

  该算法的时间复杂度为O(n)。由此可见,构造的循环不变式不同时,他们的效率也不同。对于比较难的问题,可以用“自顶向下”的设计方法,改变数学模型。

例4:设计求sin(x)=xx3/3!+x5/5!x7/7!......的算法。

/*sinx=x-x^3/3!+x^5/5-x^7/7!...*/#include <stdio.h>#include <stdlib.h>#include <math.h>int main(){    int i=1,sign=1;    float x,t,fac=1,sinx=0;    scanf("%f",&x);    t=x;    do    {        sinx+=sign*t/fac;        t=t*x*x;                   //分子t初值为x        fac=fac*(i+1)*(i+2);       //分母fac初值为1        i+=2;        sign=-sign;    }while(fabs(t/fac)>=1e-7);    printf("%f\n",sinx);    return 0;}

结果

算法分析:该算法在x的值较小时,计算的结果比较准确。但x=100等比较大的值时,误差较大。需要进一步改进。。。


参考资料:《算法设计与分析》   第二版   吕国英
转载请注明出处:http://blog.csdn.net/so_geili/article/details/71436430

0 0
原创粉丝点击