logo资料库

2016上半年程序员考试真题及答案-下午卷.doc

第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
资料共18页,剩余部分请下载后查看
【问题】
If(*set==‘\0’)
【说明】
【C代码】
2016 上半年程序员考试真题及答案-下午卷 试题一 阅读以下说明和流程图,填补流程图和问题中的空缺(1)~(5),将解答填入答题纸的对 应栏内。 【说明】 设整型数组 A[1:N]每个元素的值都是 1 到 N 之间的正整数。一般来说,其中会有一些 元素的值是重复的,也有些数未出现在数组中。下面流程图的功能是查缺查重,即找出 A[1: N]中所有缺的或重复的整数,并计算其出现的次数(出现次数为 0 时表示缺)。流程图中采 用的算法思想是将数组 A 的下标与值看作是整数集[1:N]加上的一个映射,并用数组 C[1: N]记录各整数出现的次数,需输出所有缺少的或重复的数及其出现的次数。 【流程图】 【问题】 如果数组 A[1:5]的元素分别为{3,2,5,5,1},则算法流程结束后输出结果为: (5) 输出格式为:缺少或重复的元素,次数(0 表示缺少)
参考答案: (1)A[i] (2)C[k]+1 (3)0 (4)k 和 C[k] (5)4,{1,1,1,0,2} 试题分析: (1)A[i] //A[i]赋给 K, (2)C[k]+1//C[k]值加 1,i 循环中,将 A{i}中存在的值在 C[k]中相应位数上加 1。以 A[1:5]={3,2,5,5,1}为例,当 i=1 时,k=A[1]=3,则 C[3]+1,即 C[1:5]变成{0,0,1, 0,0}。 (3)0 //判断 C[k]值是否为 0,为零这说明 k 未缺少值 (4)k 和 C[k] //k 位重复数,C[k]为重复次数 (5)在范例中,4 没有出现,1、2、3 分别出现了 1 次,5 出现了两次。
试题二 阅读以下说明和 C 代码,填补代码中的空缺,将解答填入答题纸的对应栏内。 【说明 1】 递归函数 is_elem(char ch, char *set)的功能是判断 ch 中的字符是否在 set 表示的 字符集合中,若是,则返回 1,否则返回 0。 【C 代码 1】 int is_elem (char ch ,char*set) { } If(*set==‘\0’) return 0; else If((1)) return 1; else return is_elem((2)) 【说明 2】 函数 char*combine(char* setA,char *setB)的功能是将字符集合 A(元素互异,由 setA 表示)和字符集合 B(元素互异,由 setB 表示)合并,并返回合并后的字符集合。 【C 代码 2】 char*combine(char *setA, char*setB) { int i,lenA, lenB, lenC; lenA=strlen(setA); lenB=strlen(setB); char*setC=(char*)malloc(lenA+lenB+1); if(!setC) return NULL; strncpy(setC,setA,lenA); //将 setA 的前 lenA 个字符复制后存入 setC
lenC = (3); for(i=0;i<lenB;i++) if((4)) //调用 is_elem 判断字符是否在 setA 中 setC[lenC++]=setB[i]; (5) =‘/0’; //设置合并后字符集的结尾标识 return setC; } 参考答案: (1)set[0]==ch (2)ch,*set-1 (3)lenA (4)is_elem(setB[i],*setA)==0 (5)setC[lenC+1] 试题分析: If(set[0]==ch)//取出 set 第一个元素与 ch 字符比较是否相等 return is_elem(ch,*set-1) // 从 set 第二个元素开始重新递归代入函数执行 strncpy(setC,setA,lenA); //将 setA 的前 lenA 个字符复制后存入 setC lenC=lenA; for(i=0;i<lenB;i++) ifis_elem(setB[i],*setA)==0) //调用 is_elem 判断字符是否在 setA 中 setC[lenC++]=setB[i]; setC[lenC+1]=‘/0’; //设置合并后字符集的结尾标识 returnsetC;
试题三 阅读以下说明和 C 代码,填补代码中的空缺,将解答填入答题纸的对应栏内。 【说明】 某文本文件中保存了若干个日期数据,格式如下(年/月/日): 2005/12/1 2013/2/29 1997/10/11 1980/5/15 .... 但是其中有些日期是非法的,例如 2013/2/29 是非法日期,闰年(即能被 400 整除或者 能被 4 整除而不能被 100 整除的年份)的 2 月份有 29 天,2013 年不是闰年。现要求将其中 自 1985/1/1 开始、至 2010/12/31 结束的合法日期挑选出来并输出。 下面的 C 代码用于完成上述要求。 【C 代码】 #include typedef struct{ int year, month, day;/* 年,月,日*/ }DATE; int isLeap Year(int y) /*判断 y 表示的年份是否为闰年,是则返回 1,否则返 回 0*/ { } return((y%4==0 && y%100!=0)Il(y%400==0)); int isLegal(DATE date) /*判断 date 表示的日期是否合法,是则返回 1,否则返 回 0*/ { int y=date.year,m=date.month,d=date.day;
if(y<1985 II y>2010 II m<1 II m>12 II d31) return if((m==4 ll m==6 ll m==9 II m==11)&&(1) ) return 0; If(m==2){ if(isLeap Year(y) && (2)) return 1; else if(d28) return 0; } return 1; 0; } Int Lteq(DATE d1,DATE d2) /*比较日期 d1 和 d2,若 d1 在 d2 之前或相同则返回 1,否则返回 0*/ { } Long t1,t2; t1=d1.year*10000+d1.month*100+d1.day; t2=d2.year*10000+d2.month*100+d2.day; if((3)) return 1; else return 0; int main() { DATE date,start={1985,1,1},end={2010,12,30}; FILE*fp; fp=fopen(“d.txt”,”r”); If((4)) return-1;
while(!feof(fp)){ if(fscanf(fp,”%d%d%d”,date.year,date.month,date.day)!=3) break; if((5)) /*判断是否为非法日期*/ continue; if((6)) /*调用 Lteq 判断是否在起至日期之间*/ printf(“%d%d%d\n”,date.year,date.month,date.day); } fclose(fp); Return 0; } 参考答案: (1)d>30 / d==31 或其等价表示 (2)d<29 或其等价表示 (3)t1<=t2/t1-t2<=0 或其等价表示 (4)fp==null/!fp 或其等价表示 (5)isLegal(date) 或其等价表示 (6)Lteq(start,date)==1Lteq(date,end)==1 或其等价表示 试题分析: (1)(2)理解: if((m==4 ll m==6 llm==9 II m==11)&& d>30 /d==31) return 0; //如果月份是 4,6,9,11 并且天数等于 31 则返回不合法,这几个月最多为 30 天,不可能等于 31。 If(m==2){ if(isLeap Year(y)&& d<29 ) return 1; else if (d>28) return 0;//当年份为闰年的时候,那么二月份的天数需小于或等于 28。合法则返回 1。 (3)if( t1<=t2/t1-t2<=0 ) return 1; //d1 在 d2 之前,那么表明日 期经换算成 t1、t2 后,t1<=t2。 fp==null/!fp (4)If( (5)(6)理解: )//先要判断文件是否为空; if(isLegal(date)) /*判断是否为非法日期 */ continue;
if(Lteq(start,date)==1&&Lteq(date,end)==1 ) /*调用 Lteq 判断是否在起至日期 之间,Lteq(t1,t2)的含义是比较日期 d1 和 d2,若 d1 在 d2 之前或相同则返回 1,否则 返回 0。*/
分享到:
收藏