180 likes | 415 Views
循 环 与 数 组 一、级 数 问 题 二、多 重 循 环 三、穷 举 法 四、数 组 的 应 用. 一、级数问题 级数求和要解决 2 个问题: 通项的变化规律; 求和的结束条件(按给定项数或按某种要求)。 例:习题集 P71 5 题 编写程序,计算当 时 N 的值 分析: 本题中通项的变化规律是每次分母加 1 ,求和的结束条件是 sum>10 。 for(n=1;sum<=10.0;n++)
E N D
循 环 与 数 组 一、级 数 问 题 二、多 重 循 环 三、穷 举 法 四、数 组 的 应 用
一、级数问题 级数求和要解决2个问题: 通项的变化规律; 求和的结束条件(按给定项数或按某种要求)。 例:习题集P71 5题 编写程序,计算当 时N的值 分析:本题中通项的变化规律是每次分母加1,求和的结束条件是sum>10。 for(n=1;sum<=10.0;n++) sum=sum+1.0/n;
例:习题集P72 21题 某级数的前两项A1=1,A2=1,以后各项具有关系:An=An-2+2An-1。编写程序,要求依次对于整数M=100,1000,10000求出对应的n值,使其满足Sn<M且Sn+1≥M,这里Sn=A1+A2+…+An。 分析:本题中通项的变化规律是An=An-2+2An-1,求和的结束条件是Sn<M且Sn+1≥M。按此条件,每次循环判断求和结束时都要用前一次的和Sn-1以及本次的和Sn,因此要定义2个变量分别存放两次的和,循环体中要计算本次的和Sn=Sn-1+An,若不满足结束条件,则要将本次的和保留在前一次的和的变量中,然后继续循环,直到满足条件。另外还要注意题目给出3个M的值,也就是说,级数求和要做3次,因此要再加一重循环,构成二重循环。
循环(m分别取100,1000,10000) {a1,a2,s1赋初值; for(n=3; ;n++) /* n是项数,从第3项开始*/ {计算an,s2; if(s1<m&&s2>=m){break;} else {s1=s2;a1=a2;a2=an;} } printf("n=%d\n",n-1); }
二、多重循环 多重循环是循环嵌套(循环套循环),要特别注意它的执行过程是外循环每执行一次,内循环要执行若干次。 例:习题集P71 11题 编写程序,计算500~800区间内素数的个数cnt,并按所求素数的值从大到小的顺序,计算其间隔减、加之和,即第1个素数-第2个素数+第3个素数-第4个素数+第5个素数…的值sum。 分析:按照题意,要对800~500区间(因为是从大到小)内的数逐个作出判断,而判断一个数是否为素数又要用一重循环,这样就构成了二重循环(外循环控制区间范围,内循环判断一个数是否为素数),每找出一个素数,cnt就要加1,再根据cnt的奇偶对sum进行加或减计算。
cnt=0,sum=0; 循环(i= 800~500) {判断i 是否为素数; if(i是素数) { cnt ++; 输出cnt,i; if(cnt为偶数)sum-=i; else sum+=i; } } 输出sum;
例:习题集P71 15题 编写程序验证下列结论:任何一个自然数n的立方,都等于n个连续奇数之和。例如:13=1; 23=3+5;33=7+9+11。要求程序对每个输入的自然数计算并输出相应的连续奇数,直到输入的自然数为0时止。 分析:首先考虑输入的自然数个数不确定,可用while语句对每一个数进行处理,在循环体内输入n,然后找连续n个奇数,使它们的和等于n的立方。 接下来要考虑的是连续n个奇数的起始数是未知的,因此需要循环测试。设变量k为起始数(k的初值为1),再设一个变量j从k开始循环累加连续n个奇数,若求出的和s等于n的立方,则结束测试k的循环,从k开始输出连续n个奇数,否则k=k+2;继续循环测试。
while(1) /* 该循环控制多个自然数*/ {输入一个自然数n); if(n==0)break; /*当输入0时,跳出循环 */ k=1; do /*该循环找出连续n个奇数,k是起始数 */ { s=0; for(i=1,j=k;i<=n;i++,j=j+2)s+=j; k+=2; } while(s!=n*n*n); 输出n; 输出从k开始的连续n个奇数 }
三、穷举法 穷举法是指不重复,不遗漏地穷举所有可能情况,以便从中寻求满足条件的结果。 在穷举法编程中,主要使用循环语句和选择语句。循环语句用于列举所有的可能性;而选择语句判定当前的条件是否为所求的解。 例:习题集P72 22题 一个自然数的七进制表达式是一个三位数,而这个自然数的九进制表示也是一个三位数,且这两个三位数的数码正好相反,编写程序,求这个自然数。 分析:三位九进制最大为(888)9即(728)10,三位七进制最小为(100)7即(49)10,因此要找的自然数一定在此范围内,可采用穷举法对该范围内的每一个数都判断是否满足条件。为了判断条件,要将自然数分别按九进制和七进制分解出三位数码,然后按题目给出的条件判断。
for(n=49;n<=728;n++) { 分解出七进制的三位数a1,b1,c1, 分解出九进制的三位数a2,b2,c2 if(c1==a2&&b1==b2&&c2==a1) {输出n ; 输出n的9进制三位数和7进制三位数; break;} }
四、数组的应用 对数组进行操作,通常是依靠循环来实现的。因此,数组和循环是分不开的。 例:习题集P97 3题 编写程序计算m行n列( m和n小于10)整型数组a周边元素之和(即第1行、第m行、第1列、第n列上元素之和,但是重复元素只参加1次求和)。 分析:求和时,第1行和第m行元素全部相加,第2行到第m-1行只加第1列和第n列元素。 注意求和元素的下标:第1行元素为a[0][j](j从0~n-1);第m行元素为a[m-1][j](j从0~n-1);第1列元素为a[i][0](i从1~m-2);第n列元素为a[i][n-1](i从1~m-2)。
例:习题集P97 6题 编写程序以字符串为单位,以空格或标点符号(字符串中仅含‘,’或‘.’作为标点符号)作为分隔符,对字符串中所有单词进行倒排,之后把已处理的字符串(应不含标点符号)打印出来。例如: 原文: You He Me I am a student. I like study. 结果: Me He you study like I student a am I 分析:定义一个一维数组存放原文,再定义一个二维数组存放单词,对原文进行扫描,将单词逐个分离出来,存入二维数组中(一行存放一个),原文扫描完毕,将二维数组中的单词从最后一行起,一行一行存到原来的一维数组中。
分离单词可这样做:扫描时遇分隔符给出标志(word=0; )表示一个单词结束,遇其余字符则看标志,若word=0,则是上一个单词结束,新单词开始,二维数组当前行送一个‘\0’,并换下一行,列下标从0开始,并置word=1,表示一个单词延续,然后将扫描的字符送到二维数组中;若word=1,则只需做将扫描的字符送到二维数组中。 for(i=0;(c=str[i])!='\0';i++) {if(c==' '||c==','||c=='.')word=0; else {if(word==0) {s[num][j]=0;j=0;num++;word=1;} s[num][j++]=c; } } s[num][j]=0;
原文单词倒排可这样做: for (i=num;i>0;i--) /* 控制单词个数 */ { for(j=0;s[i][j];j++) /*内循环完成一个单词的传送*/ str[k++]=s[i][j]; str[k++]=‘ ’; /* 每个单词末尾加一个空格 */ } str[k]=0; /* 最后给一维数组末尾加一个结束符*/
例:习题集P98 9题 编写程序,它能读入构成集合A,B的两组非零整数x1 ,x2 , …, xm ,y1 ,y2 ,… ,yn 。计算A与B的交集A∩B,再以由大到小的顺序输出A∩B中的元素, A∩B为空时无输出。 分析:定义数组A、B、C, A、B分别存放集合A和B,C存放A与B的交集。求与A与B交集可用A的每一个元素与B的各元素逐个比较,遇到相等的,就存入C中。这个过程需要二重循环来实现,外循环是A的变化,内循环是B的变化。输出C时要先进行由大到小的排序。
输入a,b数组元素个数; 输入a数组元素; 输入b数组元素; k=0; 循环(i=0~m-1) 循环(j=0~n-1) if(a[i]==b[j]){c[k++]=a[i];break;} if(k!=0) {对c排序; 输出c} }
例:习题集P98 16题 编写程序对字符串按下面给定的条件进行排序,排序后的结果仍按行重新存入字符串中并打印出来。 条件:从字符串中间一分为二,左边部分按字符的ASCII值降序排序,右边部分按字符的ASCII值升序排序;排序后,左边部分与右边部分进行交换。如果原字符串长度为奇数,则最中间的字符不参加排序,字符仍放在原位置上。 分析:解题步骤如下: 定义数组并输入字符串; char str[80]; gets(str); 计算字符串长度n及右边部分起始位置m; n=strlen(str); k=n/2; m=n%2==0?k:k+1;
对str[0]~str[k-1]由大到小排序; 对str[m]~str[n-1]由小到大排序; 将str[0]~str[k-1] 与str[m]~str[n-1]交换; for(i=0,j=m; i<k;i++,j++) { t=str[i];str[i]=str[j];str[j]=t; } 输出str; puts(str);