选择题:
题一:
1、设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是( )
A: n=0;while(ch=getchar()!=’\n’)n++;B: n=0;while(getchar()!=’\n’)n++;
C: for(n=0;getchar()!=’\n’;n++); D: n=0;for(ch=getchar();ch!=’\n’;n++);
答案解析:
对于for循环,其中第一项初始化表达式只执行一次,因此ch只从输入流中取一个字符,之后就再不会取字符,因此会死循环。
题二:
2、运行以下程序后,如果从键盘上输入 65 14 ,则输出结果为( )
int main()
{
int m, n;
printf(“Enter m,n;”);
scanf(“%d%d”, &m,&n);while(m!=n)//1
{
while(m>n) m=m-n; //2
while(n>m) n=n-m; //3
}
printf(“m=%d\n”,m);
return 0;
}
A: 3B: 2C: 1 D: 0
答案解析:
此题技巧是耐心,考查while循环和循环嵌套的理解,初值m=65,n=14;循环1判断m!=n为真,来到循环2判断m>n为真,执行m=m-n;直到m=9,n=14;循环2结束来到循环3判断n>m为真,执行n=n-m;直到m=9,n=5;循环3结束回到循环1,如此往复直到m==n时,循环结束。
题三:
3、若运行以下程序时,从键盘输入 ADescriptor ,则下面程序的运行结果是( )
#include
int main()
{
char c;
int v0=0,v1=0,v2=0;
do
{
switch(c=getchar())
{
case’a’:case’A’:
case’e’:case’E’:
case’i’:case’I’:
case’o’:case’O’:
case’u’:case’U’:v1 += 1;
default:v0+= 1;v2+=1;
}
}while(c!=’\n’);
printf(“v0=%d,v1=%d,v2=%d\n”,v0,v1,v2);
return 0;
}
A: v0=7,v1=4,v2=7 B: v0=8,v1=4,V2=8
C: v0=11,v1=4,v2=11 D: v0=12,v1=4,v2=12
答案解析:
代码switch语句中没有break,则每次找到入口进入后,顺序执行到代码块结束为止。例如当c为’A’时,从case ‘A’进入,先后执行v1+=1;v0+=1;v2+=1;,而当c为’p’时,从default进入,先后执行v0+=1;v2+=1;,容易看出最终v0和v2是相等的。
题四:
4、如下函数是求两个int数字最大公约数的,指出其中存在的问题【多选】( )
int gcd(char x,char y)
{
int min = x A: 参数类型不对 B: 循环变量min初值不对 C: 判断等于的符号不对 D: 返回类型不对
答案解析:
1.函数实参是int,形参用char不对,会发生截断丢失数据;2.min在for循环开始时更新为0,不再是两个形参中的较小值;3.判断是否整除的时候误将==写成=赋值运算符;4.函数最终要返回一个int值,返回值类型没问题,但是这里要强调一个选项中没写出的问题,如果是牛客网上的题,会报编译错误,说该函数不是在所有情况下都有返回值,只有在if条件成立的情况下有返回值,一般在vs上这种情况能通过,编译器会给一个默认的返回值。
题五:
5、执行下面的程序段,语句3的执行次数为( )
for(i = 0; i <= n-1; i++) // (1)
for(j = n; j > i; j–) // (2)
state; // (3)
A: n(n+2)/2B: (n-1)(n+2)/2 C: n(n+1)/2 D: (n-1)(n+2)
答案解析:
外循环有n次,当i=0,内循环为n次,当i=1,内循环为n-1次,当i=2时,内循环为n-2次,以此类推,总次数为n+(n-1)+(n-2)+……+2+1,就是个等差数列,等于n(n+1)/2。
编程题:
题一:错误的集合
645. 错误的集合 – 力扣(LeetCode)
示例:
输入:nums = [1,2,2,4]
输出:[2,3]
思路一:
排序法:由于题目没有说明数组是否有序,所以需要我们自己将数组排序,才能去遍历;同时需要知道的是returnSize是指返回数组元素的个数。
第一步:使用qsort()函数将数组排序成升序;
第二步:为返回值数组开辟动态内存空间,否则在出函数时会释放;
第三步:定义一个数来记录数组的前一个数;
第四步:遍历数组:相同记录为num[0],数组当前元素-前一个元素值大于一说明中间的就是缺的元素num[1];
第五步:如果最后一个元素不等于长度,说明最后一个就是缺的元素。
int my_cmp(const void* p1,const void* p2){return *(int*)p1 - *(int*)p2;}int* findErrorNums(int* nums, int numsSize, int* returnSize){//将数组进行升序排序qsort(nums,numsSize,4,my_cmp);//returnSize为返回数组元素个数*returnSize = 2;//开辟动态内存空间,否则在出函数时会释放int* num = (int*)malloc(sizeof(int)*2);//定义数组的前一个数int front = 0;//遍历数组for(int i = 0; i 1){num[1] = nums[i]-1;}front = nums[i];}//最后一个元素不等于长度,说明最后一个就是缺的元素if(nums[numsSize-1] != numsSize){num[1] = numsSize;} return num;}
思路二:
使用标记的方式就可以找出重复的数字,数组中出现过哪个数字就把对应数字作为下标在对应位置1,表示已经标记出现过,如果哪个数据对应位已经置1,则表示就是重复的数字。有了重复的数字,拿 [1, n] 的总和减去去掉重复数据的数组总和就是丢失的数据。 其实使用标记法时出现的数字对应位每次 ++ ,则最后出现0次的就是丢失,出现2次的就是重复的,这样的方式也可以,不过需要多次遍历。
int* findErrorNums(int* nums, int numsSize, int* returnSize){*returnSize = 2;//遍历nums数组,将其中数据对应的位置1, 哪一位如果已经重置过则意味着数据重复了int *arr = (int *)calloc(numsSize + 1, sizeof(int));//申请numsSize个整形空间,并初始化为0int *ret = (int *)calloc(*returnSize, sizeof(int));//申请2个整形空间,并初始化为0int cur_sum = 0, old_sum = 0;for (int i = 0; i < numsSize; i++) {if (arr[nums[i]] == 1) { //这个数字在上边数组的对应位置已经置过1了,则重复ret[0] = nums[i];//找到重复的数字} arr[nums[i]] = 1; //将标记数组的对应数据位置1old_sum += i + 1; // 1~n的求和cur_sum += nums[i]; //当前数组中的数据求和(多了一个重复的,少了一个丢失的)} ret[1] = old_sum - (cur_sum - ret[0]);//原始总和,减去去掉重复后的当前总和就是丢失的数字free(arr);return ret;}
题二:密码检查
密码检查_牛客题霸_牛客网 (nowcoder.com)
示例1
输入:
1CdKfIfsiBgohWsydFYlMVRrGUpMALbmygeXdNpTmWkfyiZIKPtiflcgppuR
输出:
YES
思路一:
暴力的不能再暴力的方法:
第一步:创建输入密码数量的n,和字符串arr;
第二步:for循环遍历,创建用于记录密码的字符是否正确count,顺便求字符串长度;
第三步:判断字符串长度是否合法;
第四步:遍历一遍字符串,格式正确就记录count;
第五步:最后将字符串长度与count比较,相同“YES”,反之“NO”。
int main() {int n = 0;scanf("%d",&n);//字符串长度限制char arr[100] = {0};//密码个数for(int j = 0;j = 8 && sz <= 100){//遍历一遍字符串,格式正确就记录for(int i = 0;i = 'A' && arr[i] = 'a' && arr[i] = '0' && arr[i] <='9'){count++;}}}//长度对比if(sz == count){printf("YES\n");}else {printf("NO\n");}}return 0;}