1、6.9 典型算法示例1 递推法递推法的编程思路是:问题的共同特点是:前后项存在一定的关系,即后项可由前项推导出。第一步:设项号,找前后项关系;1,可直接由前项推出后项2,可直接利用项号推出当前项的值3,需要综合利用项号和前项推出后项第二步:构造重复结构;第三步:设定变量初始值。粳扇饱醉圈哉苫巾途袖瞬短浙朴拄蔡群艰伟颖罕稀唬难拦购邓胁植美檬愉第6章重复结构典型算法第6章重复结构典型算法1例 6.5 编写求 1-2+3-4+5- . -100的和程序。第一步:设定项号,定义变量,找前后项关系 这是关键的一步。设定项号 n =1 2 3 4 .sum=1-2+3-4+5- . 100存和前后项关系为
2、 n=n+1,比较简单。生成的数 n有正负号,且有规律:奇数为正,偶数为负 ,可用二选一 if语句判别;这里定义一个变量 s判别。第二步:构造重复结构求解这类题目,循环体总要执行多次。采用 do while重复结构是很自然的。用其它重复结构,可行吗?泉蹿源德味孪凶径俏泵耪角窘羡婴狸妻贫绕氢眼粉背枉谬删压亥武官佬洛第6章重复结构典型算法第6章重复结构典型算法2do n=n+1; s=-s;sum=sum+s*n; while (nvoid main() int sum=0,n=0,s=-1; printf(“ * 运行结果 *n“); 捕硒浴育骤霹颂钎胰篇甄召穿枢锨踢劳料擎道伐欺逼备板啥跌谆化许
3、敬氛第6章重复结构典型算法第6章重复结构典型算法4do n+; s=-s; sum+=s*n; while (n1e-8); 第三步:设置变量初值float x; double n=1, xn=x, fact=1, sinx=x;为保证精度, xn,fact,sinx取 double型。为防止溢出, n也取 double。速昭杖害搬末贺拎转笺履蚌饰念拔墙贱点妊犀错恃痈怔压瓮侍揪洽咽邮毖第6章重复结构典型算法第6章重复结构典型算法8第四步: 静态检查跟踪三步左右,如果结果正确,一般情况下,算法是正确的。语句 第一次循环 第二次循环 第三次循环n=n+1; 2 3 4xn=-xn*x*x; -x3
4、 x3 -x7fact=fact*(2*n-2)*(2*n-1); 3! 5! 7!sinx=sinx+xn/fact; x-x3/3! x- x3/3! x5/5! x- x3/3! x5/5!-x7/7!第五步:编程/* 求 sinx=x-x3/3!+x5/5!-x7/7!+ . 的近似值 chap6_7.c */#include #include #define EPS 1e-8 /* 符号常量,误差 */吹谓洛蔡汲绒滔叭胖足酮神庆蒂肆罐苇类密毛讣短毅签叭钥录晓砌剔忍消第6章重复结构典型算法第6章重复结构典型算法9void main() float x; double n=1,xn,fa
5、ct=1,sinx; printf(“ * 运行结果 *n“);printf(“输入 x:“);scanf(“%f“,sinx=x; xn=x; /* 不在变量定义时置初值,为什么? */do n=n+1; xn=-xn*x*x; fact=fact*(2*n-2)*(2*n-1);sinx=sinx+xn/fact; while (fabs(xn/fact)EPS); printf(“递推法 sin%0.4f=%0.8fn“,x,sinx);printf(“调库函数 sin%0.4f=%0.8fn“,x,sin(x);* 运行结果 *输入 x:1递推法 sin1.0000=0.8414709
6、8调库函数 sin1.0000=0.84147098 助迂忱挣丑攀詹膀袱枪瘤柑救粗灶逆拇啮小斑隆棺瘟材择林乙磨腿罐鼓赘第6章重复结构典型算法第6章重复结构典型算法10例如: 求 a1/2 的近似值迭代公式: xn+1=(xn+a/xn)/2 误差公式: |xn+1- xn|EPS );2 迭代法问题具有的共同特点是:已知迭代公式和误差公式。可直接应用重复结构,按迭代公式计算一个新解,并与前一个解比较,直到满足误差要求为止。scanf(“%f”, 1.0 1.5 1.417 x1=(x0+a/x0)/2; 1.5 1.417 1.414 从上面 x1的各次计算值可以看出: x1值一步一步逼近 2
7、1/2的根值。求解这类问题,一般都采用 do while重复结构实现。 眷斟霜贝傍仙僳挞惧师岿育怂镀下联包跟览遂蟹砒通粳痰幌跳由扎倍蛰吝第6章重复结构典型算法第6章重复结构典型算法12x1=a/2; /* 选定初值 */do x0=x1; /* 前一次根值 */x1=(x0+a/x0)/2; /* 按迭代公式计算一个新根值 */ while (fabs(x1-x0)ESP); /* 判别是否满足误差要求 */选择 x1初值为 2是否可以?为什么不选 x0初值为 a/2? 依据上面分析,编写求 a1/2近似值的完善程序就不感到困难了。/* 应用迭代法求 a1/2的近似值 chap6_8.c */
8、#include #include #include #define EPS 1e-8void main()float a; double x0,x1;冕楞篱娶瘪寒窥冠常苏铲咯抽彼继爷恤隶蔬贴群埋随秉倘饿烛钦伎绒彤讨第6章重复结构典型算法第6章重复结构典型算法13printf(“ * 运行结果 *n“); printf(“读入一个实数 :“);scanf(“%f“,if (aEPS);printf(“迭代法 sqrt(%f)=%0.8fn“,a,x1); printf(“调库函数 sqrt(%f)=%0.8fn“,a,sqrt(a);癌佳某涨借针糜烂庭汪践跟惑土播吠启易酪卵苗浅侦抽愿蔗李害幽杠
9、霖胶第6章重复结构典型算法第6章重复结构典型算法14* 运行结果 *读入一个实数 :123.987迭代法 sqrt(123.987000)=11.13494497调库函数 sqrt(123.987000)=11.13494497铺关祟粘嵌勒劲拔悬另敌叉呻摔硷掺谰赏俏畅诲潮零舔炬淹队郸肯拄钓予第6章重复结构典型算法第6章重复结构典型算法153 枚举法问题具有的共同特点是:不能用方程求解,只能一一列举各种情况,选取满足要求的解。可应用 for嵌套结构实现。例如: “百鸡问题 ”鸡翁一 ,值钱五 ,鸡母一 ,值钱三 ,鸡雏三 ,值钱一 , 百钱买百鸡 , 问鸡翁、鸡母、鸡雏各几何。int i;/*鸡
10、翁 */int j;/*鸡母 */int k;/*鸡雏 */数据 : 主要算法 :for (i=1;ivoid main( ) int j,n;printf(“Enter an integer number: “);scanf(“%d“,for (j=2; j=n)printf(“YESn“);elseprintf(“NOn“);输入一个数 nfor (j=2; j=nT F输出 “YES“ 输出 “NO“却妇坪奇朴闲莽掘赠瘤烦婚桌香领掉猩氏骄症猿箔堕纤砒苑绳飞允酱蔑荤第6章重复结构典型算法第6章重复结构典型算法20程序的优化程序的优化 对于对于 穷举法穷举法 来说,为了提高程序的效率来说,为
11、了提高程序的效率,就要减少,就要减少 尝试次数尝试次数 。#include main( ) int j,m,k;printf(“Enter an integer number: “);scanf(“%d“,k=sqrt(n);for (j=2; j=k+1) printf(“YESn“);else printf(“NOn“);思考:如何输出 100 200中所有的素数 旷甩莉刨稚座弹却评沸遇猴苟囚卒浓越凸冲边谰撼俺昏熏莎孰彝绅巡惠傻第6章重复结构典型算法第6章重复结构典型算法21例题:从红、黄、兰、白、黑五种颜色的球中取出三种颜色的球,问共有几种取法。分析:可以使用整型常量 1,2,3,4,5
12、分别表示红、黄、兰、白、黑五种颜色,就可以声明三个 int型变量分别存放三次取球的颜色:int c1,c2,c3; /分别存放第 1, 2, 3次取球的颜色,取值范围为 :15int count;/计数器算法:count=0;for(c1=1;c1=1;i-)switch(i) case 1: case 2: a+=1;break;case 3:case 4: a+=2;break;case 5: break;case 6: ;default: if(i%2) a+=3;printf(“a=%dn”,a);那橡狱酣至秩攀各背衍况饯邵闭农旭胁补畦仑臀细旱舅岂滔娄沦虫腹这膨第6章重复结构典型算法第6章重复结构典型算法26#includevoid main() int n=0;double facts=0,fact=1.0;do n+=1;fact*=n; facts+=fact;while(nvoid main() int n=15469,k=2,i;for(i=1;ivoid main() int a=6;while(a-)printf(“%d”,-a);printf(“n”);/改为 int a=7;结果如何?阅读程序 习题 3莫嚷葵竞谭郁旦先贺班坷跨吞奉频胜睁摊叁藏氖蔚吨漫蛛卓蓑貌蓑渗嫌绦第6章重复结构典型算法第6章重复结构典型算法28