当前位置: 首页 > news >正文

【C语言16天强化训练】从基础入门到进阶:Day 12


 🔥个人主页:艾莉丝努力练剑

❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、洛谷刷题、C/C++基础知识知识强化补充、C/C++干货分享&学习过程记录

🍉学习方向:C/C++方向学习者

⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平

前言:距离我们学完C语言已经过去一段时间了,在学习了初阶的数据结构之后,博主还要更新的内容就是【C语言16天强化训练】,之前博主更新过一个【C语言刷题12天IO强训】的专栏,那个只是从入门到进阶的IO模式真题的训练。【C语言16天强化训练】既有IO型,也有接口型。和前面一样,今天依然是训练五道选择题和两道编程算法题,希望大家能够有所收获!



目录

1.1  题目1

1.2  题目2

1.3  题目3

1.4  题目4

1.5  题目5

二、两道算法题

2.1  数字颠倒

2.1.1  题目理解

2.1.2  思路

2.1.3  实现(C/C++)

2.2  单词倒排

2.2.1 题目理解

2.2.2 思路

2.2.3  实现(C/C++)

结尾


一、五道选择题

1.1  题目1

题干:请阅读以下程序,其运行结果是( )

int main()
{char c='A';if('0'<=c<='9') printf("YES");else printf("NO");return 0;
}

A. YES     B. NO     C. YESNO     D. 语句错误

解析:正确答案就是A选项。

'0'<=c<='9'并非判断x大于等于字符0,小于等于字符9,而是先执行'0'<=c,使用这个表达式的结果再和'9'比较,'0'的ASCII码值是48,'A'的ASCII码值是'65',故'0'<c是真值1,1无疑是小于字符'9'的,最终是真,即选项A“YES”。

1.2  题目2

题干:假设编译器规定 int 和 short 类型长度分别为32位和16位,若有下列C语言语句,则 y 的机器数为( )

unsigned short x = 65530;
unsigned int y = x;

A. 0000 7FFA     B. 0000 FFFA     C. FFFF 7FFA     D. FFFF FFFA

解析:正确答案就是B选项。

unsigned short类型的x变量2个字节保存了65530,十六进制形式为0xFFFA,x给y赋值时会整型提升,而无符号数在提升时高位补0,其实就相当于把x的值放在了y的低2个字节的空间中,故选B。

1.3  题目3

题干:下列程序的输出结果是什么( )

#include<stdio.h>
int main()
{int n = 1001;int ans = 0;for(int i = 1; i <= n; ++i){ans ^= i % 3;}printf("%d",ans);return 0;
}

A. -2     B. 0     C. 1     D. 2

解析:正确答案就是B选项。

可以这样解释:

i % 3 的值按1、2、0循环,可推算出ans按1、3、3、2、0、0循环,循环进行1001次,而1001%6=5,也就是ans按规律得到的第5个数为最终结果,故ans=0。

也可以这样解释:

循环计算1001次 i % 3 的异或。i % 3 的值每3次循环(0,1,2)重复,异或结果:0^1^2=3(二进制11,即3),但每3次重复。1001/3=333组余2(最后余i=1000和1001:1000%3=1,1001%3=2)。
每组3次异或结果为3(但ans初始0),每组的异或值:0^1^2=3,但连续异或333组:由于3的二进制为11,异或多次时,取决于次数。
实际上,每两组异或会抵消:3^3=0,所以333组(奇数组)异或后为3,再异或最后两个(1和2):3^1^2=0(因为3^1=2, 2^2=0)。

因此最终ans=0。

1.4  题目4

题干:C语言中,下列运算符优先级最高的是 ( )

A. !      B. %      C. >>      D. ==

解析:正确答案就是A选项。

单目运算符的优先级通常都比较高,具体情况可查阅运算符优先级表格。

运算符优先级:

!(逻辑非)优先级最高(单目运算符),

%(取模)和 >>(右移)为算术运算符,优先级次之,

==(相等)优先级较低。
因此优先级最高的是 !

1.5  题目5

题干:要使 a 的低四位翻转,需要进行操作是( )

A. a | 0xF      B. a & 0xF      C. a ^ 0xF      D. ~a

解析:正确答案就是C选项。

十六进制数0xF是4位1,参与运算时整型提升,高位都是0。低四位和1异或,0^1是1,1^1是0;高位和0异或,0^0是0,1^0是1。故而可以通过异或F使得a的低四位翻转,并保持高位不变。

也可以这样解释:

要使低四位翻转(即0变1,1变0),应使用异或操作:a ^ 0xF (0xF二进制为00001111,异或后低四位取反,高位不变)。

其他:

a | 0xF 低四位置1,a & 0xF 只保留低四位,~a 所有位取反。

选择题答案如下:

1.1  A

1.2  B

1.3  B

1.4  A

1.5  C

校对一下,大家都做对了吗?


二、两道算法题

2.1  数字颠倒

牛客网链接:HJ11 数字颠倒

题目描述:

2.1.1  题目理解

为了解决这个问题,我们需要将给定的非负整数颠倒后以字符串形式输出,包括任何前导零。关键在于如何处理数字的每一位,并确保颠倒后的字符串正确表示原数字的逆序。

2.1.2  思路

1、问题分析输入是一个非负整数,需要将其数字顺序颠倒后输出。

例如,输入1516000应输出0006151。

2、关键点直接使用数学运算逐位提取数字,从最低位开始输出,这样可以自然形成颠倒后的字符串,包括前导零。

3、算法选择通过循环取模运算获取最后一位数字,并将其转换为字符输出,然后通过整数除法移除已处理的数字。重复此过程直到所有数字处理完毕。

4、复杂度分析该算法的时间复杂度为O(d),其中d是数字的位数,因为每个数字处理一次。空间复杂度为O(1),仅使用固定空间。

2.1.3  实现(C/C++)

这道题是IO型的,下面是C语言的模版(如果是IO型就可以不用管它们了)——

代码演示:

//C语言实现
#include <stdio.h>int main()
{int n;scanf("%d", &n);if (n == 0){printf("0");}else{while (n){printf("%c", '0' + n % 10);n /= 10;}}return 0;
}

时间复杂度O(n)

空间复杂度O(1)

1、输入处理读取输入的整数n。

2、特殊情况处理如果n为0,直接输出"0"。

3、数字颠倒对于非零的n,通过循环每次取n的最后一位数字(使用取模运算),转换为对应的字符并输出。随后通过整数除法移除已处理的数字。

4、输出结果循环直到所有数字处理完毕,输出的字符串即为颠倒后的数字,包括任何前导零。

这种方法高效且直接,确保了正确性和简洁性。

当然还有比这个更加简洁的写法:do while——

代码演示:

//C语言实现——方法2
#include <stdio.h>
int main()
{int a;scanf("%d", &a);do {printf("%d", a % 10);a /= 10;} while (a);return 0;
}

时间复杂度O(n)

空间复杂度O(1)

当然还有一种写法:

代码演示:

//C语言实现——方法3
#include <stdio.h>
int main()
{int num;while (~scanf("%d", &num)) {if (num == 0) {//0的情况特殊处理,因为0不会进入while循环计算余数,因此不会被打印printf("%d", num % 10);continue;} while(num > 0) {printf("%d", num % 10);//打印一个数字的个位数 129 % 10 得到9num /= 10;//通过除以10的方式去掉个位数 例如:129/10 得到12}printf("\n");} return 0;
}

时间复杂度O(n)

空间复杂度O(1)

我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——

代码演示:

//C++实现
#include <iostream>
using namespace std;int main()
{int n;cin >> n;if (n == 0){cout << '0';}else{while (n){cout << char('0' + n % 10);n /= 10;}}return 0;
}

时间复杂度:O(n),空间复杂度:O(1)

我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!

2.2  单词倒排

牛客网链接:HJ31 单词倒排

题目描述:

2.2.1 题目理解

我们需要将输入字符串中的单词(仅由大小写字母组成)提取出来,然后逆序输出,单词之间用单个空格分隔。非字母字符作为分隔符。

2.2.2 思路

1、读取输入使用getline(C++)或fgets(C)读取整行输入。

2、提取单词遍历字符串中的每个字符,如果是字母则添加到当前单词,否则结束当前单词(如果非空)并添加到单词列表。

3、处理最后一个单词在遍历结束后,检查是否还有未添加的单词。

4、逆序输出从单词列表的末尾开始向前输出,单词之间用空格分隔。

这种方法确保了单词的正确提取和逆序输出,同时处理了各种非字母分隔符的情况。

2.2.3  实现(C/C++)

这道题是IO型的,下面是C语言的模版(如果是IO型就可以不用管它们了)——

代码演示:

//C语言实现
#include <stdio.h>
#include <ctype.h>
#include <string.h>int main()
{char s[10001]; // 总字符长度不超过10^4fgets(s, sizeof(s), stdin);char words[5000][21]; // 假设最多5000个单词,每个单词最长20int count = 0;int idx = 0;int len = strlen(s);for (int i = 0; i < len; i++){if (isalpha(s[i])){// 将字母添加到当前单词words[count][idx++] = s[i];}else{if (idx > 0){words[count][idx] = '\0'; // 结束当前单词count++;idx = 0;}}}if (idx > 0){ // 处理最后一个单词words[count][idx] = '\0';count++;}// 逆序输出单词for (int i = count - 1; i >= 0; i--){printf("%s", words[i]);if (i > 0) printf(" ");}printf("\n");return 0;
}

时间复杂度:O(n*m),空间复杂度:O(1)

这个的代码量还是很大的,可以再简洁一点——

代码演示:

//C语言实现——方法2
#include <stdio.h>
#include <string.h>
int main() 
{char str[10001] = { 0 };//题目要求:字符串最长10000int row = 0;while (gets(str) > 0) {char* ptr = str;char* word[10000] = { NULL };while (*ptr != '\0') {//如果是个字母字符,则是单词的起始字符if (('z' >= *ptr && *ptr >= 'a') || ('Z' >= *ptr && *ptr >= 'A')) {word[row++] = ptr;//保存每个单词的起始地址//把本次的单词字母字符走完,直到遇到非字母字符while (*ptr != '\0' &&(('z' >= *ptr && *ptr >= 'a') || ('Z' >= *ptr && *ptr >= 'A'))) {ptr++;}continue;//不能继续向下,因为下面的ptr++会跳过当前的非字母字符}*ptr = '\0';//把非字母的数据全部替换为结尾标志ptr++;}for (int i = row - 1; i >= 0; i--) {printf("%s ",word[i]);//针对所有单词的起始地址逆序打印即可}printf("\n");}
}

时间复杂度:O(n*m),空间复杂度:O(1)

我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——

代码演示:

//C++实现
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using namespace std;int main()
{string s;getline(cin, s); // 读取整行输入vector<string> words;string word;for (char c : s){if (isalpha(c)){ // 如果是字母,添加到当前单词word += c;}else{if (!word.empty()){ // 遇到非字母字符,且当前单词非空,则添加到列表words.push_back(word);word.clear();}}}if (!word.empty()){ // 处理最后一个单词words.push_back(word);}// 逆序输出单词for (int i = words.size() - 1; i >= 0; --i){cout << words[i];if (i > 0) cout << " ";}cout << endl;return 0;
}

时间复杂度:O(n*m),空间复杂度:O(1)

我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!


结尾

本文内容到这里就全部结束了,希望大家练习一下这几道题目,这些基础题最好完全掌握!

往期回顾:

【C语言16天强化训练】从基础入门到进阶:Day 11

【C语言16天强化训练】从基础入门到进阶:Day 10

【C语言16天强化训练】从基础入门到进阶:Day 9

【C语言16天强化训练】从基础入门到进阶:Day 8

【C语言16天强化训练】从基础入门到进阶:Day 7

【C语言16天强化训练】从基础入门到进阶:Day 6

【C语言16天强化训练】从基础入门到进阶:Day 5

【C语言16天强化训练】从基础入门到进阶:Day 4

【C语言16天强化训练】从基础入门到进阶:Day 3

【C语言16天强化训练】从基础入门到进阶:Day 2

【C语言16天强化训练】从基础入门到进阶:Day 1

结语:感谢大家的阅读,记得给博主“一键四连”,感谢友友们的支持和鼓励!

http://www.dtcms.com/a/353620.html

相关文章:

  • 归档和压缩
  • 摄像头镜头模组的设计要点
  • ES03-常用API
  • 安装了TortoiseSVN但是在idea的subversion里面找不到svn.exe
  • Dify 从入门到精通(第 59/100 篇):Dify 的自动化测试(进阶篇)
  • Python爬虫实战:构建音乐作品电商平台数据采集与分析系统
  • Highcharts Stock :打造专业级金融图表的利器
  • Apache DolphinScheduler:数据治理中数据质检利器
  • 机器学习 TF-IDF方法
  • 使用MP4视频格式链接地址的自适应视频弹窗实现方案HTML代码
  • 智能体协作体系核心逻辑:Prompt、Agent、Function Calling 与 MCP 解析
  • 流量迷局 - 理解负载均衡(L4/L7)与CDN背后的“隐形路由
  • 全球首款Al勒索软件PromptLock:跨平台攻击新威胁, Windows/macOs/Linux均受影响
  • Python 数据分析学习笔记:Pandas 数据索引
  • 通信协议接口
  • 设计模式8-命令模式
  • docker常用命令有哪些
  • ASM字节码框架和KSP能够解析JAR包或者AAR包里面的内容吗?
  • 碰一碰发视频手机版源码开发:支持OEM
  • 76 最小覆盖子串
  • CPTS-Reddish
  • 【开发配置】云服务器配置Gitlab服务
  • 解决pod install报错问题的一些方法
  • 合金弹头全系列游戏合集分享 电脑安卓手机掌机SWITCH整合版 (1/2/X/3/4/5/6/7/XX)
  • Elasticsearch数据迁移快照方案初探(二):快照创建与多节点存储问题解决
  • Kafka经典面试题--Kafka的其他问题汇总
  • 嵌入式第三十九天(TCP多任务并发)
  • C语言二级考试环境配置详细教程【mac篇】
  • Java设计模式之《亨元模式》
  • HttpRequest.get()方法报错:301 Moved Permanently