C语言刷题指南(四)

 

📙作者简介: 清水加冰,目前大二在读,正在学习C/C++、Python、操作系统、数据库等。

📘相关专栏:C语言初阶C语言进阶C语言刷题训练营数据结构刷题训练营、有感兴趣的可以看一看。

欢迎点赞 👍 收藏 ⭐留言 📝 如有错误还望各路大佬指正!

✨每一次努力都是一种收获,每一次坚持都是一种成长✨       

在这里插入图片描述

目录

 前言

1. 选择题

📖题目1:

📖题目2:

📖题目3:

📖题目4:

📖题目5:

2. 编程题

📖题目一

📖题目二

 总结


 前言

        本期是C语言刷题的第四期,该系列的内容都为本人在刷题中遇到的,不同类型且具有典范性的题目,这些题目的算法思想非常直到学习,以及对基础的考察都十分细致,如对知识有遗忘,可参考C语言系列专栏。


1. 选择题

📖题目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只从输入流中取一个字符,之后就再不会取字符,因此会死循环

正确答案:D

📖题目2:

若运行以下程序时,从键盘输入 ADescriptor<回车> ,则下面程序的运行结果是( )
 

#include <stdio.h>
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语句。

        代码switch语句中没有break,则每次找到入口进入后,顺序执行到代码块结束为止。例如当c为'A'时,从case 'A'进入,先后执行v1+=1;v0+=1;v2+=1;,而当c为'p'时,从default进入,先后执行v0+=1;v2+=1;,容易看出最终v0和v2是相等的


正确答案:D

📖题目3:

执行下面的程序段,语句3的执行次数为( )
 

for(i = 0; i <= n-1; i++) // 语句(1)
for(j = n; j > i; j--) // 语句(2)
state; // 语句(3)

A: n(n+2)/2

B: (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

正确答案:C

📖题目4:

对于代码段,下面描述正确的是( )
 

t=0;
while(printf("*"))
{
    t++;
    if (t<3)
        break;
}

A、其中循环控制表达式与0等价

B、其中循环控制表达式与'0'等价

C、其中循环控制表达式是不合法的

D、以上说法都不对
 

✨题目解析:

        printf(“*”)函数调用的返回值是字符串中字符的个数,即为1。所以while后面的条件恒为真,所以循环控制表达式与'0'是等价的(字符'0'不是0)。正确答案是B

正确答案:B

📖题目5:

在c语言中,一个函数不写返回值类型,默认的返回类型是( )

A、int

B、char

C、void

D、都不是

✨题目解析:

一个函数不写返回值类型,默认的返回类型是int,但不提倡这么做


正确答案:A

2. 编程题

📖题目一

题目描述:

 示例:

 题目链接:

错误的集合icon-default.png?t=N6B9https://leetcode.cn/problems/set-mismatch/

✨题目解析:

        这道题目的解法有很多,但今天我主要向大家介绍一种新的解题思想与方法,这种方法可适用于许多类似的题目当中,那就是——标记法

思路:

        使用标记的方式就可以找出重复的数字,数组中出现过哪个数字就把对应数字作为下标在对应位置,置为1。表示已经标记出现过,如果哪个数据对应位已经置1,则表示就是重复的数字。

        有了这个思路我们带入到题目当中,通过这个方法我们可以找到重复的数据,有了重复的数字,拿 [1, n] 的总和减去,去掉重复数据的数组总和,就是丢失的数据。

具体代码如下:

int* findErrorNums(int* nums, int numsSize, int* returnSize){
    *returnSize=2;
    int* arr=(int*)malloc(sizeof(int)*(numsSize+1));
    int* ret=(int*)malloc(sizeof(int)*2);
    int sum1=0,sum2=0;
    for(int i=0;i<numsSize;i++)
    {
        if(arr[nums[i]]==1)    //这个数字在上边数组的对应位置已经置过1了,则重复
        {
            ret[0]=nums[i];    //找到重复的数字
        }
        arr[nums[i]]=1;        //将标记数组的对应数据位置1
        sum1+=i+1;             // 1~n的求和
        sum2+=nums[i];         //当前数组中的数据求和(多了一个重复的,少了一个丢失的)
    }
    ret[1]=sum1-sum2+ret[0];   //原始总和,减去去掉重复后的当前总和就是丢失的数字
    free(arr);                 //最后释放掉用于标记的数组
    return ret;
}

        注意:新开的数组要比原数组的空间多一个,例如原数组大小为4(也就是n),数据是1、2、2、4,数据是从1到n的整数,如果用标记法,就需要使用原数组中的数据作为数组下标进行标记,而数组下标从0开始,要想不越界就必须创建5个空间的数组,这样才能有下标4.

📖题目二

题目描述:

 示例:

 题目链接:

统计不同字符的个数icon-default.png?t=N6B9https://www.nowcoder.com/practice/eb94f6a5b2ba49c6ac72d40b5ce95f50?tpId=37&&tqId=21233&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

✨题目解析:

        我们已经知道了标记法,接下来我们趁热打铁,继续来看这道题,这道题目的条件非常适合使用标记法。

思路:

        首先把a字符( ascii 值为 97 )作为下标,将标记数组的第 97 位置 1 ,下次如果还有 a 字符出现,到下标 'a' 或者 97 的位置一看是1就表示a已经统计过了。

代码实现如下:

#include <stdio.h>

int main() {
    char str[501];
    char* pst=str;
    int arr[128]={0};
    int count=0;
    scanf("%s", str) ;
        while(*pst!='\0')
        {
            if(arr[*pst]!=1)
            {
                count++;
            }
            arr[*pst++]=1;
        }
       printf("%d",count) ;
    
    return 0;
}

        通过这两道题目的练习,我们会发现,标记法这种方法具有局限性,使用数组来标记,就必须要开足够大的空间,如果给的数组范围太大,如1000000,这种开辟数组就非常难了,空间占用也大,所以标记法不适用于数据范围过大的情况。

 总结


        本期我们提供了对C语言基础练习的选择题,以及新算法思想的实践练习,本系列内容也属于我个人编程语言学习笔记的一个总结,最后,我要衷心感谢每一位读者,你们的支持和参与是我前进的动力。希望你们在C语言的学习和编程之路上继续努力,不断追求卓越。祝愿你们在未来的编程之旅中取得更大的成功和成就!

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值