1循环与数组一、级数问题二、多重循环三、穷举法四、数组的应用2一、级数问题级数求和要解决2个问题:通项的变化规律;求和的结束条件(按给定项数或按某种要求)。例:习题集P715题编写程序,计算当时N的值分析:本题中通项的变化规律是每次分母加1,求和的结束条件是sum10。for(n=1;sum=10.0;n++)sum=sum+1.0/n;1014131211NSUM3例:习题集P7221题某级数的前两项A1=1,A2=1,以后各项具有关系:An=An-2+2An-1。编写程序,要求依次对于整数M=100,1000,10000求出对应的n值,使其满足SnM且Sn+1≥M,这里Sn=A1+A2+…+An。分析:本题中通项的变化规律是An=An-2+2An-1,求和的结束条件是SnM且Sn+1≥M。按此条件,每次循环判断求和结束时都要用前一次的和Sn-1以及本次的和Sn,因此要定义2个变量分别存放两次的和,循环体中要计算本次的和Sn=Sn-1+An,若不满足结束条件,则要将本次的和保留在前一次的和的变量中,然后继续循环,直到满足条件。另外还要注意题目给出3个M的值,也就是说,级数求和要做3次,因此要再加一重循环,构成二重循环。4循环(m分别取100,1000,10000){a1,a2,s1赋初值;for(n=3;;n++)/*n是项数,从第3项开始*/{计算an,s2;if(s1m&&s2=m){break;}else{s1=s2;a1=a2;a2=an;}}printf(n=%d\n,n-1);}5二、多重循环多重循环是循环嵌套(循环套循环),要特别注意它的执行过程是外循环每执行一次,内循环要执行若干次。例:习题集P7111题编写程序,计算500~800区间内素数的个数cnt,并按所求素数的值从大到小的顺序,计算其间隔减、加之和,即第1个素数-第2个素数+第3个素数-第4个素数+第5个素数…的值sum。分析:按照题意,要对800~500区间(因为是从大到小)内的数逐个作出判断,而判断一个数是否为素数又要用一重循环,这样就构成了二重循环(外循环控制区间范围,内循环判断一个数是否为素数),每找出一个素数,cnt就要加1,再根据cnt的奇偶对sum进行加或减计算。6cnt=0,sum=0;循环(i=800~500){判断i是否为素数;if(i是素数){cnt++;输出cnt,i;if(cnt为偶数)sum-=i;elsesum+=i;}}输出sum;7例:习题集P7115题编写程序验证下列结论:任何一个自然数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;继续循环测试。8while(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个奇数}9三、穷举法穷举法是指不重复,不遗漏地穷举所有可能情况,以便从中寻求满足条件的结果。在穷举法编程中,主要使用循环语句和选择语句。循环语句用于列举所有的可能性;而选择语句判定当前的条件是否为所求的解。例:习题集P7222题一个自然数的七进制表达式是一个三位数,而这个自然数的九进制表示也是一个三位数,且这两个三位数的数码正好相反,编写程序,求这个自然数。分析:三位九进制最大为(888)9即(728)10,三位七进制最小为(100)7即(49)10,因此要找的自然数一定在此范围内,可采用穷举法对该范围内的每一个数都判断是否满足条件。为了判断条件,要将自然数分别按九进制和七进制分解出三位数码,然后按题目给出的条件判断。10for(n=49;n=728;n++){分解出七进制的三位数a1,b1,c1,分解出九进制的三位数a2,b2,c2if(c1==a2&&b1==b2&&c2==a1){输出n;输出n的9进制三位数和7进制三位数;break;}}11四、数组的应用对数组进行操作,通常是依靠循环来实现的。因此,数组和循环是分不开的。例:习题集P973题编写程序计算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)。12例:习题集P976题编写程序以字符串为单位,以空格或标点符号(字符串中仅含‘,’或‘.’作为标点符号)作为分隔符,对字符串中所有单词进行倒排,之后把已处理的字符串(应不含标点符号)打印出来。例如:原文:YouHeMeIamastudent.Ilikestudy.结果:MeHeyoustudylikeIstudentaamI分析:定义一个一维数组存放原文,再定义一个二维数组存放单词,对原文进行扫描,将单词逐个分离出来,存入二维数组中(一行存放一个),原文扫描完毕,将二维数组中的单词从最后一行起,一行一行存到原来的一维数组中。13分离单词可这样做:扫描时遇分隔符给出标志(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;14原文单词倒排可这样做:for(i=num;i0;i--)/*控制单词个数*/{for(j=0;s[i][j];j++)/*内循环完成一个单词的传送*/str[k++]=s[i][j];str[k++]=‘’;/*每个单词末尾加一个空格*/}str[k]=0;/*最后给一维数组末尾加一个结束符*/15例:习题集P989题编写程序,它能读入构成集合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时要先进行由大到小的排序。16输入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}}17例:习题集P9816题编写程序对字符串按下面给定的条件进行排序,排序后的结果仍按行重新存入字符串中并打印出来。条件:从字符串中间一分为二,左边部分按字符的ASCII值降序排序,右边部分按字符的ASCII值升序排序;排序后,左边部分与右边部分进行交换。如果原字符串长度为奇数,则最中间的字符不参加排序,字符仍放在原位置上。分析:解题步骤如下:定义数组并输入字符串;charstr[80];gets(str);计算字符串长度n及右边部分起始位置m;n=strlen(str);k=n/2;m=n%2==0?k:k+1;18对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;ik;i++,j++){t=str[i];str[i]=str[j];str[j]=t;}输出str;puts(str);