【C语言】初阶数据结构相关习题(一)

【C语言】初阶数据结构相关习题(一)


🎆个人主页:夜晚中的人海

在这里插入图片描述

今日语录:人的生命似洪水在奔流,不遇着岛屿、暗礁,难以激起美丽的浪花。——奥斯特洛夫斯基

文章目录

⭐一、判定是否互为字符重排

题目描述:判定是否互为字符重排

在这里插入图片描述

解题思路:
1.首先判断两个字符串长度是否相等,若不相等,那么他们不可能彼此排列,直接返回false。

2.若字符串长度相等,我们就可以使用qsort函数对两个字符串进行排序来判断它们是否排列。

qsort 是标准库中的快速排序函数,它需要以下参数:
• 要排序的数组(s1 和 s2)。
• 数组的长度(len1 和 len2)。
• 每个元素的大小(sizeof(char))。
• 比较函数(cmp)。

3.排序完成后,如果两个字符串是彼此的排列,那么它们排序后的结果应该完全相同,因此我们就可以使用strncmp函数来比较排序后的字符串。

代码实现:

intcmp(constvoid* a,constvoid* b){return*(char*)a -*(char*)b;} bool CheckPermutation(char* s1,char* s2){int len1 =strlen(s1);int len2 =strlen(s2);if(len1 != len2){return false;}qsort(s1,len1,sizeof(char),cmp);qsort(s2,len2,sizeof(char),cmp);if(strncmp(s1,s2,len1)==0){return true;}return false;}

🎉二、 回文排列

题目描述:回文排列

解题思路:
1.我们首先要理解回文字符串的特性,一个字符串可以通过重新排列形成回文字符串的条件是:如果字符串长度为偶数,那么每个字符必须出现偶数次;如果字符串长度为奇数,那么最多只能有一个字符出现奇数次其余字符必须出现偶数次

2.我们使用一个大小为 128 的数组 a 来统计每个字符的出现次数(假设字符集为 ASCII,其范围为 0-127)。

3.遍历字符串 s,将每个字符的 ASCII 码值对应的数组位置加一。

4.遍历数组 a,统计出现次数为奇数的字符个数,如果某个字符的出现次数是奇数,则count 加一。

5.如果 count 大于等于 2,说明有多个字符的出现次数为奇数,这种情况下无法形成回文字符串,直接返回 false。

6.遍历完数组后,如果count的值小于2,说明最多只有一个字符的出现次数为奇数,这种情况下可以构成回文字符串,则返回 true。

代码实现:

bool canPermutePalindrome(char* s){int len =strlen(s);int a[128]={0};int count =0;for(int i =0;i < len;i++){//将字符所对应的ASCII码值位置++ a[s[i]]++;}for(int i =0;i <128;i++){if(a[i]%2==1){ count++;}if(count >=2){return false;}}return true;}

🚀三、字符串压缩

题目描述:字符串压缩

在这里插入图片描述

解题思路:
1.首先判断特殊情况,如果字符串的长度小于等于2,则压缩后的字符串长度并不会小于原始字符串,因此直接返回源字符串。

2.分配一个足够大的内存空间用于存储压缩后的字符串。初始化计数器count 为 1,用于记录当前字符的连续出现次数;初始化指针 p 为 0,用于记录压缩后字符串的当前位置。

3.使用一个循环从第 1 个字符开始遍历字符串,直到字符串末尾。如果当前字符与前一个字符相同,则计数器 count 加一;如果当前字符与前一个字符不同,则将前一个字符及其出现次数写入压缩后的字符串。(将字符写入 ret[p],并将指针 p 向后移动一位;使用sprintf函数将计数器 count 转换为字符串并写入 ret[p],同时更新指针 p 的位置。重置计数器 count 为 1,开始统计下一个字符的连续出现次数。)

4.遍历完成后,比较压缩后的字符串长度与原始字符串长度,如果压缩后的字符串长度大于原始字符串长度,则返回原始字符串,否则返回压缩后的字符串。

代码实现:

char*compressString(char* S){int len =strlen(S);char* ret =(char*)malloc(sizeof(char)*len*2);int count =1;int p =0;int n =0;if(len <=2){return S;}for(int i =1;i < len +1;i++){if(S[i]== S[i -1]){ count++;}else{ ret[p]= S[i -1]; p++; n =sprintf(&ret[p],"%d",count); p = p + n; count =1;}}if(strlen(ret)> len){return S;}else{return ret;}}

🎡四、递归乘法

题目描述:递归乘法

在这里插入图片描述

解题思路:
1.我们可以理解乘法其实就是重复的加法。如:A×B 可以表示为将 A 加上自身 B 次。

2.如果B>1时,则该问题就可以被分解为A×B=A+(A×(B−1));当 B=1 时,乘积直接等于 A,因为任何数乘以 1 都等于它本身。

3.每次递归调用都会返回一个部分结果,最终将所有部分结果累加起来,得到最终的乘积。

代码实现:

intmultiply(int A,int B){int ret =0;if(B >1){ ret +=multiply(A,B-1)+ A;}else{ ret = A;}return ret;}

🏠五、取近似值

题目描述:取近似值

在这里插入图片描述

解题思路:
1.我们要理解当浮点数强制类型转化为整型时,它是只向上调整的,并不会进行四舍五入的操作。

2.因此我们可以先将浮点数加上0.5,然后在进行强制类型转换。如果小数部分大于或等于 0.5,则加上 0.5 后会触发向上取整;若小数部分小于0.5,则加上 0.5 后不会触发向上取整。(这一方法只适用于浮点数为正数时)

代码实现:

#include<stdio.h>intmain(){int ret =0;float n;scanf("%f",&n);printf("%d\n",(int)(n +0.5));}

🏝️六、数列

题目描述:数列

在这里插入图片描述

解题思路:
1.定义一个足够大的数组 arr,用于存储生成的伪随机数序列,将数组的前两个元素初始化为 1 和 2。

2.使用循环从第 3 个元素开始,根据递推公式生成后续的序列值,每个元素的值由前两个元素计算得出,并对 32767 取模,以确保值不会超出 long 类型的范围。

3.由于数组索引从 0 开始,而用户输入的索引从 1 开始,因此需要将用户输入的索引值减 1,以获取对应的数组元素。

代码实现:

#include<stdio.h>intmain(){long arr[1000000]={1,2};for(int i=2;i<1000000;i++){ arr[i]=(arr[i-1]*2+ arr[i-2])%32767;}long n;scanf("%ld",&n);for(int i =0;i<n;i++){int num;scanf("%d",&num);printf("%ld\n",arr[num-1]);}return0;}

🚆七、搜索插入位置

题目描述:搜索插入位置

在这里插入图片描述

解题思路:
1.定义两个指针 low 和 high,分别指向数组的起始位置和结束位置。定义一个变量 tmp,用于存储每次二分查找的中间索引。

2.使用 while 循环进行二分查找,计算中间索引 tmp。比较目标值 target 与中间值 nums[tmp]

3.如果循环结束仍未找到目标值,说明目标值不存在于数组中。如果目标值小于所有数组元素,low 会保持为0;如果目标值大于所有数组元素,low 会逐渐增加到 numsSize;如果目标值位于数组的某个位置之间,low 会停在目标值应该插入的位置。

代码实现:

intsearchInsert(int* nums,int numsSize,int target){int low =0;int high = numsSize -1;int tmp =0;while(low <= high){ tmp =(low + high)/2;if(nums[tmp]== target){return tmp;}elseif(nums[tmp]>target){ high = tmp -1;}else{ low = tmp +1;}}return low;}

🚘八、搜索旋转排序数组

题目描述:搜索旋转排序数组

在这里插入图片描述

解题思路:
1.首先要找到旋转点,使用二分查找的方法。如果 nums[0] > nums[numsSize - 1],说明数组确实被旋转了。

2.每次比较 nums[mid] 和 nums[left],如果 nums[mid] > nums[left],说明 mid 在前半部分的升序子数组中,旋转点在右半部分。否则,旋转点在左半部分。最终,left 和 right 会收敛到旋转点的位置。

3.确定查找范围。找到旋转点后,根据目标值 target 的大小,确定在哪个子数组中进行查找。如果 target 在前半部分的范围内,则在前半部分进行查找;否则,在后半部分进行查找。

4.使用标准的二分查找算法在选定的子数组中查找目标值。如果循环结束仍未找到目标值,则返回 -1。

代码实现:

intsearch(int* nums,int numsSize,int target){int left =0,right = numsSize -1;int mid = numsSize -1;while(nums[0]> nums[numsSize -1]&& left < right){ mid =(left + right)/2;if(nums[mid]>nums[left]){ left = mid;}else{ right = mid;}}//前半部分查找if(nums[0]<= target){ left =0,right = mid;}//后半部分查找else{ left = mid +1,right = numsSize -1;}while(left <= right){ mid =(left + right)/2;if(nums[mid]== target){return mid;}elseif(nums[mid]< target){ left = mid +1;}else{ right = mid -1;}}return-1;}

🏖️九、二进制链表转整数

题目描述:二进制链表转整数

在这里插入图片描述

解题思路:
1.使用一个指针 pcur 遍历链表,统计链表的节点个数。

2.再次从头节点开始遍历链表,计算二进制数的十进制值。

3.将每个节点的值乘以对应的权重 2 的(count−1)次方 ,权重从最高位开始计算,因此每次遍历时 count 减 1。将每个节点的值累加到结果 ret 中。

4.遍历完成后返回目标值ret即可。

代码实现:

typedefstructListNode ListNode;intgetDecimalValue(structListNode* head){ ListNode* pcur = head;int count =0;int ret =0;//记录链表的结点个数while(pcur){ count++; pcur = pcur->next;} pcur = head;//再次从头开始遍历链表,计算结果while(pcur){ ret +=(pcur->val)*pow(2,count -1); count--; pcur = pcur->next;}return ret;}

今天的分享就到这里啦,如果感到不错,希望能给博主一键三连,感谢大家的支持!希望这篇文章可以帮到大家,我们下期再见!

Read more

SpringBoot+Vue 线上辅导班系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】

SpringBoot+Vue 线上辅导班系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】

摘要 随着互联网技术的快速发展,线上教育已成为现代教育的重要组成部分,尤其是在后疫情时代,线上辅导的需求显著增长。传统的线下辅导模式受限于时间和空间,难以满足学生个性化学习的需求,而线上辅导班系统能够突破这些限制,提供灵活、高效的学习方式。该系统旨在为学生和教师搭建一个便捷的互动平台,支持课程管理、在线学习、作业提交、实时答疑等功能,从而提升学习效率和教学质量。关键词:线上教育、辅导班系统、Java Web、SpringBoot、Vue。 本系统采用前后端分离架构,后端基于SpringBoot框架实现,提供RESTful API接口,前端使用Vue.js框架构建用户界面,确保系统的高效性和可维护性。数据库采用MySQL存储数据,并通过MyBatis-Plus实现数据持久化操作。系统主要功能包括用户管理(学生、教师、管理员角色)、课程管理、在线学习、作业提交与批改、实时聊天等。系统设计注重用户体验,支持响应式布局,适配多种终端设备。通过JWT实现安全的用户认证与授权,保障数据隐私。关键词:SpringBoot、Vue.js、MySQL、

By Ne0inhk
【Actix Web】Rust Web开发实战:Actix Web框架全面指南

【Actix Web】Rust Web开发实战:Actix Web框架全面指南

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,ZEEKLOG全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Rust开发,Python全栈,Golang开发,云原生开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。 所属的专栏:Rust语言通关之路 景天的主页:景天科技苑 文章目录 * Rust Web开发 * 一、Actix Web框架概述 * 1.1 Actix Web的特点 * 1.2 Actix Web与其他Rust框架比较

By Ne0inhk
Flutter for OpenHarmony:web_socket 纯 Dart 标准 WebSocket 客户端(跨平台兼容性之王) 深度解析与鸿蒙

Flutter for OpenHarmony:web_socket 纯 Dart 标准 WebSocket 客户端(跨平台兼容性之王) 深度解析与鸿蒙

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 虽然 dart:io 提供了 WebSocket 类,dart:html 也提供了 WebSocket 类,但这种“分裂”的 API 设计让编写跨平台(同时支持 Mobile/Web/Desktop)的代码变得异常痛苦。你需要使用条件导入 (if (dart.library.io) ...) 来分别处理。 web_socket 库就是为了解决这个问题而诞生的。它提供了一个统一的、平台无关的WebSocket 接口。 无论你的代码运行在 Android、iOS、Web 还是 OpenHarmony 上,它都会自动选择最底层的实现(在鸿蒙上通常是 dart:io)

By Ne0inhk
【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题

【踩坑记录】使用 Layui 框架时解决 Unity WebGL 渲染在 Tab 切换时黑屏问题 在开发 Web 应用时,尤其是集成了 Unity WebGL 内容的页面,遇到一个问题:当 Unity WebGL 渲染内容嵌入到一个 Tab 中时,切换 Tab 后画面会变黑,直到用户点击黑屏区域,才会恢复显示。 这个问题通常是因为 Unity 渲染在 Tab 切换时被暂停或未能获得焦点所致。 在本文中,我们将介绍如何在使用 Layui 框架时,通过监听 Tab 切换事件并强制 Unity WebGL 渲染恢复,来解决这一问题。 1. 问题描述 当 Unity WebGL 内容嵌入到页面中的多个

By Ne0inhk