计算机三级上机南开100题难题解析_第1页
计算机三级上机南开100题难题解析_第2页
计算机三级上机南开100题难题解析_第3页
计算机三级上机南开100题难题解析_第4页
计算机三级上机南开100题难题解析_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、计算机三级上机南开100题 难题解析前言对于南开100题中难度较大的几道题,题的答案程序都比较长,死记硬背不好背下来,关键是要在心里明确并牢记要完成题目指定的功能所需完成的步骤!心中清楚了需要完成的步骤,在考场上你只要根据这些步骤编制一定的代码实现就可以了!所以关键是要知道“要做什么”,知道了“要做什么”后至于“怎么做”,只要你的C语言基础过关就可以办到!再换句话说就是:要想写出代码先要清楚完成指定功能的“算法”!心中明确了“算法”,那么你只需按部就班转化为C语言程序代码即可!另外声明:我下面的讲解有的很废话,语言很累赘,一是由于个人水平所限,二是由于我想尽量把题目解析得浅显易懂面面俱到!所以

2、尽管语言很烦冗,但个人认为还是很浅显易懂的!这些文字只是本人第一次准备三级上机的心得总结,由于本人水平有限,如有错误之处欢迎交流,批评指正!本人觉得南开100题中最难的也就三四道题。其中就包括字符串处理问题。这种题型涉及到了南开100题的第三、四题。下面先解析南开100题的第四题。同意转载但请表明出处:南开100题第四题首先明确函数的功能是:以行为单位对行中以空格或标点符号为分隔的所有单词进行倒排。最后把已处理的字符串(应不含标点符号)仍按行重新存入字符串数组xx中。木易版参考答案:void StrOL(void) int i,j,k,s,m,strl; char str80; for(i=0

3、;i<maxline;i+) strl=strlen(xxi); memset(str,0,80); /*初始化这字符串数组str*/ s=k=0; for(j=strl-1;j>=0;j-) /*从当前字符串尾部开始向前倒序循环,实现题意要求的倒排*/ if(isalpha(xxij) k+; /*如果当前字符是字母az或AZ,则k加一*/ else for(m=1;m<=k;m+) /*否则将长度为k的单词顺序存入到字符串数组str中,s值加1*/ strs+=xxij+m; k=0; /*将k值清0,以方便下一个单词的长度计数*/ if(!isalpha(xxij) s

4、trs+=' ' /*如果当前字符不是字母az或AZ,则以空格代之存入到字符串数组str中,s值加一*/ for(m=1;m<=k;m+) /*此时的k值为当前字符串中第一个单词的长度,但在上一个for循环中没能存入到字符串数组str中,所以在这里将其存入到str中*/ strs+=xxij+m; strs='0' /*在当前行尾加0以标记此行的结束*/ strcpy(xxi,str); /*将倒排好的当前字符串重新存回到当前行xx中*/ 清楚变量:程序代码中:变量s:用于扫描每行字符串,变量k:用于扫描每个单词。字符串变量str80:用于存储每行处理完的

5、字符。每行全部处理完后,即该行单词全部逆序排好后就将此字符串暂存变量赋值给原字符串全局变量xx5080。步骤:确定最外层循环:for(i=0;i<maxline;i+)每行字符串处理又需要一个循环:for(j=strl-1;j>=0;j-)从每行尾部开始逆序扫描每行字符串。 向前扫描过程中是字母的继续前行;当遇到非字母字符,则停住,这样就确定了一个单词,将前面刚确定的这个单词存入字符串变量中! 存好前面这个单词后将接下来的这个非字母字符变为空格,然后继续向前扫描。一直在每行字符串的循环中反复执行,直至逆序扫描至该行行首!注意事项:开始先将字符串暂存变量初始化为空。代码是memset

6、(str,0,80); 接着每行字符串扫描完处理完都要先将字符串暂存变量初始化为空后,再接着扫描处理下一行字符串!故代码memset(str,0,80); 要么放在两个循环for(i=0;i<maxline;i+)和for(j=strl-1;j>=0;j-) 之间要么也可以放在for(j=strl-1;j>=0;j-)循环体的最前面!与类似,每扫描并确定了一个单词,都要将变量k重新初始化赋值为0。(另外须注意:在程序处理字符串前,最最开始时s=0;k=0;)每行扫描的最后一个单词,即每行原字符串的第一个单词都未及时存入字符串暂存变量中!由于算法中,从后向前扫描字符串,只有当碰

7、到了非字母字符时,才确定了一个单词并将刚刚确定的前面一个单词立即存入到字符串暂存变量中。因此当每行扫描完最后一个单词(即每行原字符串的第一个单词)扫描到了行首,循环条件j>=0限制自动停止扫描,该循环结束,由于存入单词功能的代码在该循环循环体中,故原字符串的第一个单词都未及时存入,所以要记得将最后一个扫描的单词存入到字符串暂存变量中,然后再进行下一行的扫描!每行字符串处理完要记得在字符串暂存变量尾部添加'0'标记行结束!代码是strs='0'每行处理完的字符串已经存入到字符串暂存变量str中,最后要记得将其复制到原字符串全局变量xx中。然后将str初始化为

8、空,继续下一行的扫描处理,周而复始直至文章全部处理完最终结束。同意转载但请表明出处:南开100题第三题首先明确函数的功能是:StrOR( )函数的功能是:以行为单位依次把字符串中所有小写字母o左边的字符串内容移到该串的右边存放,然后把小写字母o删除,余下的字符串内容移到已处理字符串的左边存放,之后把已处理的字符串仍按行重新存入字符串数组xx中。正确理解题意并分析出算法:理解题意并分析算法,这个思考过程最为重要,我认为这是攻克本题的关键!首先抽象一个模型:假设要处理的字符串模型是:aobocod那么根据题意很容易知道处理的步骤分别是:aobocodbocodacodabdabc同理再分析字符串a

9、bcodefogh,最后的结果是:ghabcdef这样我们很容易就发现了一个规律:题目中原字符串的最后处理效果原来就是:将字符串中最后一个小写字母o左右两侧的内容互换,并消除所有小写字母o即可。想通了这个规律,相应的算法也就确定了,那么这道题也就不难了!(就这个算法让我苦恼了好几天一直也不懂,终于在一次下晚自习回宿舍的路上通过上面这种模型抽象的方法想通了!我觉得我的智商并不算高,我也不是学计算机专业的,我用这种方法想通了,大家也应该没问题了吧。)木易版参考答案:void StrOR(void)int i,righto,j,s,k; char tem80; for(i=0;i<maxlin

10、e;i+) for(j=strlen(xxi)-1;j>=0;j-) /*倒序循环*/ k=0; memset(tem,0,80); /*初始化字符串tem*/ if(xxij='o')  /*如果当前字符为'o',进入以下语句*/ righto=j; /*则将此字符中位置j的值赋给righto*/ for(s=righto+1;s<strlen(xxi);s+) temk+=xxis; /*从righto的下一跳开始将其后所有的字符都存入到tem中*/ for(s=0;s<righto;s+) /*从当前行首部开始到出现字符'

11、;o'的位置(righoto)之前开始循环*/ if(xxis!='o') temk+=xxis; /*将不是字符'o'的字符全存入到tem中*/ strcpy(xxi,tem); /*将当前已处理的字符重新存入当前行xx*/ else continue; 参考答案二:void StrOR(void) int i,righto,j,k;char tem80;for(i=0;i<maxline;i+) k=0;righto=0;memset(tem,0,80); /*上面这两行初始化语句要么放在两循环中间,要么放在内循环循环体最前面。 */ for(

12、j=strlen(xxi)-1;j>=0;j-) /*倒序循环*/if(xxij='o') righto=j;break; /*寻找最右边的小写字母o的位置,将其下标存储到righto中*/for(j=righto+1;j<strlen(xxi);j+) /*将righto右边的字符串存入到tem中 */temk+=xxij;for(j=0;j<righto;j+) /*将righto左边的字符串存入到tem中 */if(xxij!='o') temk+=xxij; 此处有必要加大括号么?strcpy(xxi,tem); /*将已处理完的该行字

13、符重新存入当前行xx*/上面两种答案我经过上机验证都没有问题。清楚变量:变量righto:用于存储字符串最右边(right)的一个小写字母o的位置(下标)。字符串变量tem80:字符串暂存变量,在字符串处理过程中边处理边把处理好的字符串暂存到该字符数组中。每行全部处理完后,就将此字符串暂存变量赋值给原字符串全局变量xx5080。步骤:与题目四类似也是先要确定两个大的循环架子:确定最外层循环:for(i=0;i<maxline;i+)每行字符串处理又需要一个循环:for(j=strlen(xxi)-1;j>=0;j-)也是个倒序的循环。倒序扫描每行字符串从每行字符串串尾开始由后向前扫

14、描,碰到小写字母o就停住,这样就确定了该字符串最右边的一个小写字母o的位置,并记录其下标将其存放在变量righto中。接着将该行最右边的小写字母o的右边(后面)的字符串 按照从字母o至行末的顺序全部存入到字符串暂存变量tem中。对应循环代码是for(j=righto+1;j<strlen(xxi);j+) 。将该行最右边一个小写字母o左边(前面)的的字符串 按照从行首至该行最右边小写字母o的顺序存入到字符串暂存变量tem中。对应循环代码是for(j=0;j<righto;j+)。另外注意:根据算法,步骤只存入不是小写字母o的字母,所以勿忘在存入代码temk+=xxij;前面加上一个

15、条件语句:if(xxij!='o')这样字符串暂存变量中存放的就是已经处理好的该行的字符串了。然后将此字符串暂存变量中处理好的字符复制存入到原字符串数组中。这样该行字符串处理完毕。然后字符串暂存变量初始化清零继续参与下一行的处理,周而复始直至文章全部处理完最终结束。注意事项:初始化语句k=0;righto=0;memset(tem,0,80);要在每次即将开始处理一行新字符串前先执行,所以该语句要么放在最外层两循环之间,要么放在第二个循环的循环体的最前面。总结方法:在南开100题里只要是读取一篇英文文章再对文章的字符串进行指定处理的题目。一般都是要涉及到一个二维数组用来存放字符

16、串。在编制程序代码时也一般都要用到两个大的循环架子,即外循环控制各个行,内循环控制每行的各个字符的扫描!这点应该熟练到只要一见到这类题就应该作出的第一本能反映,上来就应该先写出这俩循环架子来!这也算是一个作题规律吧!南开100题的第三题和第四题也基本都是沿用这么一个框架:那就是先定义一个字符串暂存变量,然后在处理每行字符串的过程中,边处理边把该行已经处理好的字符存入到已定义的字符串暂存变量中,最后等该行全部处理完毕,字符串暂存变量中所存储的就是已经处理好的该行的字符串,然后再把它复制到原二维数组中即可。接着把字符串暂存变量初始化清零,再参与下一行的处理!这也算是一个规律吧!初始化语句的位置也是

17、应该注意的,前面已经说到,就不再赘述。同意转载但请表明出处:南开第57题出圈题是南开100题中最难的三道题之一!我个人认为南开100题中有三道题的难度很大,分别是字符串处理问题,对应的是南开第三题和第四题!这两道题前面本人已经分析过了,另外一道难题就是下面我即将分析的南开第57题出圈问题!关于出圈问题网上也有不少讲解,这里我就不再赘述,我只是补充些网上没有涉及到的,读者可以参考补充阅读!首先理解题意设有n个人围坐一圈并按顺时针方向从1到n编号。从第s个人开始进行1到m的报数, 报数到第m个人, 此人出圈, 再从他的下一个人重新开始1到m的报数,如此进行下去直到所有的人都出圈为止。现要求按出圈次

18、序,给出这n个人的顺序表p。木易版答案:void Josegh(void) int i,j,s1,w; s1=s; for(i=1; i<=n; i+) pi-1=i; for(i=n; i>=2; i-) s1=(s1+m-1)%i; if(s1=0) s1=i; w=ps1-1; for(j=s1; j<i; j+) pj-1=pj; pi-1=w; 这里提出几个广泛流传的错误!本人在学习此题过程中发现,不管是网上还是书店的一些参考书中,对此题的讲解都有一些错误!本人在这里提出几个广泛流传的错误,希望大家指正! 南开上机题或无忧上机题的题干错误!原题干:若第i个人报数后出

19、圈,则将pi置于数组的倒数第i个位置上,而原来第i+1个至倒数第i个元素依次向前移动一个位置。举个例子:套用原题干:若第10个人报数后出圈,则将p10置于数组的倒数第10个位置上,而原来第11个至倒数第10个元素依次向前移动一个位置。上面这句话显然不对!而实际上是:原列队第10个人报数后出圈(即编号为10的人报数出圈),则将p9置于数组的倒数第1个位置上,而原来第11个至倒数第1个元素依次向前移动一个位置。或这么表述:第1个报数后出圈的人(因为编号为10的人是第1个报数出圈的),将p9置于数组的倒数第1个位置上,而原来第11个至倒数第1个元素依次向前移动一个位置。错误分析:编题的人没有搞清其实

20、“出圈次序”“出圈人编号”“出圈人所对应的数组下标”是三个不同的概念!如:第一个出圈的人,出圈次序是1,下标是p9,编号是10。而编题人简单地都用i表示了!显然不对!这里我认为本句话应该改为:第i个人报数出圈的人,将“此人的编号”置于数组的倒数第i个位置上。 市面上卖的谭浩强主编的三级C语言上机指导一书中(清华大学出版社2005年7月第1版封皮是红色的价格是22.00元)对此题的解释也有错误:讲解中说:s1=(s1+m-1)%i的作用是找出报数后出圈人的下标。本人认为编者也犯了类似的错误:应该改为:s1=(s1+m-1)%i的作用是找出报数后出圈人的“编号”。因为变量s1表示的不是出圈人的所对

21、应的数组下标,而是其“编号”。清楚变量:变量i:表示没有出圈的人数。变量s1:表示出圈人所对应的编号。编号s1=ps1-1。变量w:暂存变量,用于暂时存放刚刚出圈人的编号。数组p:存放出圈人编号的数组。程序结束后,该数组按出圈次序倒序存放出圈人的编号。步骤: 建立数组,应注意:p下标=编号 ;下标=编号-1;编号s1=ps1-1。对应代码是:for(i=1; i<=n; i+) pi-1=i; 倒序循环for(i=n; i>=2; i-),找出出圈人的“编号”s1。对应的算法是通过求余得到的!s1=(s1+m-1)%i; 将刚出圈人的编号先寄存在暂存变量中。 将刚出圈的人之后至原队

22、列最后一个未出圈的人依次在数组中前移一位。对应的代码是:for(j=s1; j<i; j+) pj-1=pj; 将刚出圈人的编号放置在最后一个未出圈的人的后面,即pi-1的位置上。注意事项:此题有两种变形,差别在于出圈人编号的存放顺序。考生应注意考题中是哪种变形!形式一:若第i个人报数后出圈,则将此人编号置于数组的倒数第i个位置上,而原来第i+1个至倒数第i个元素依次向前移动一个位置;即第1个出圈的编号存放在pn-1中,第2个出圈的编号存放在pn-2中,直至第n个出圈的编号存放在p0中。对应的void WriteDat(void) 函数中的循环语句是for(i=N-1; i>=0;

23、 i-)形式二:第1个出圈的编号存放在p0中,第2个出圈的编号存放在p1中,直至第n个出圈的编号存放在pn-1中。对应的void WriteDat(void) 函数中的循环语句是for(i = 0 ; i <= N - 1 ; i+)上面答案是形式一的答案。若遇到形式二,考生须在原有答案的基础上再增加两个循环以使循序颠倒过来!for(i=0,j=n-1;i<n,j>=0;i+,j-) /*也可改为for(i=0,j=n-1;i<n;i+,j-) */     qj=pi;   for(i=0;i<n;i+

24、)     pi=qi;由于求余的作用,当报数人正好到最后一个人时s1为0,故要有if(s1=0) s1=i;根据题意,开始时莫忘设置s1=s;同意转载但请表明出处:南开100题各类型题目考点总结作者:崔欢 西南石油大学第1类:产品销售五个因素的记录比较排序strcmp()函数PRO结构体类型的声明与定义比较法排序第2类:奇偶判断及计算注意精度,强制类型转换(double)注意题93题还要求写关于文件读取的代码!第3类:连续五个数的问题注意循环条件莫越界:iMAX-5或起始i=5标志变量的运用第4类:素数问题会编写判断素数的自定义函数最好单独编一个判断素数的自定义函数在main()函数的外边(例如题51)第5类:将数分解后操作会熟练运用%,/一个四位数的各位拆分:千位数thou=n/1000;百位数hun=n%1000/100=n/100%10;十位数t

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论