C语言练习题第三弹!!!绝对典中典!!!

news2024/9/19 11:03:14

目录

1.单身狗1

1.1 题目

1.2 分析推理

1.3 代码实现

2.单身狗2

2.1 题目

2.2 分析推理

2.3 代码实现

3.字符串左旋

3.1 题目

3.2 分析推理

3.3 代码实现

3.3.1 方法一

3.3.2 优化一

3.3.2.1 思路分析

 3.3.2.2 strcpy函数和strncat函数

3.3.2.3 代码实现

3.3.3 优化二

3.3.3.1 思路分析

3.3.3.2 代码实现

4.字符串旋转结果

4.1 题目

4.2 分析推理

4.3 代码实现


1.单身狗1

1.1 题目

在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。

例如:

数组中有:1 2 3 4 5 1 2 3 4,只有5出现一次,其他数字都出现2次,找出5

1.2 分析推理

这里我们借助一个操作符:^ ----按位异或--->对应的二进制位上相同则为0,相异则为1

满足交换律;eg:1^2 ^1=2

类似消消乐一样

那我们顺着这个思路往下,就可以将整个数组的元素都^ ,最后的结果就是我们要找的单身狗

1.3 代码实现

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = 0;
	for (int i = 0; i < sz; i++)
	{
		ret ^= arr[i];
	}
	printf("单身狗是%d", ret);
	return 0;
}


2.单身狗2

2.1 题目

一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。编写一个函数找出这两个只出现一次的数字。

例如:

有数组的元素是:1,2,3,4,5,1,2,3,4,6

只有5和6只出现1次,要找出5和6.

2.2 分析推理

我们发现刚刚把里面所有的数字都异或一遍,利用异或的方法不成立了。如果有两个数字都只出现了一次,那么如此得到的应该是两个数异或的结果。

例子中异或的结果也就是5^ 6=0011

在单身狗1的基础上,我们再来想想办法:

首先这个结果肯定不是0(要不然就全都配对了),所以里面一定至少一位是一找出值为1的一位,以这一位的值将结果分为两组。这样的话,就可以延用单身狗1的方法了。

例如1 2 3 4 1 2,异或完的结果应该是3^4得到的111,那么随便找一位就行了。例如找最低位,那么这最低位是1的有1 3 1,最低位是0的有2 4 2,由于是利用异或结果为1的某一位分的组,所以两个待查询数字一定分别在两组中。所以再找两个变量,分别异或两组数,即可找到这两个数。

2.3 代码实现

#include<stdio.h>
void findnum(int arr[], int sz, int* ret1, int* ret2)
{
	//整体异或
	int ret = 0;
	for (int i = 0; i < sz; i++)
	{
		ret ^= arr[i];
	}
	//找到何处为1
	int pos = -1;//位置上的值不是0就是1,-1可以避免影响
	//从右往左,遇到1,就记录1的位置
	for (int i = 0; i < 32; i++)
	{
		if ((ret & 1) == 1)//&---按位与--->全1则为1,有0则0
		{
			pos = i;//记录1所在位置
			break;
		}
	}
	//分组分别异或
	for (int i = 0; i < sz; i++)
	{
		if ((arr[i] >> pos) & 1)//右移pos位找到pos位上的值按位与
		{
			*ret1 ^= arr[i];
		}
		else
		{
			*ret2 ^= arr[i];
		}
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,4,3,2,1 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//返回值
	int ret1 = 0;
	int ret2 = 0;
	findnum(arr, sz, &ret1, &ret2);//传址
	printf("单身狗是%d,%d\n", ret1, ret2);
	return 0;
}


3.字符串左旋

3.1 题目

实现一个函数,可以左旋字符串中的k个字符。

例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

3.2 分析推理

设计循环使其可以旋1次,然后让他执行n次是一个最简单的思路:一个一个慢慢挪

我们按照下标顺序一个一个将第一个下标对应的字符现存放到tmp空间,再将tmp中存放的字符放到数组最后一个下标对应的位置,以此类推

但是,值得注意的是多次左旋结果可能相同

例如:ABCD---4个字符--->左旋1,5,9......等次数的结果一样--->BCDA

3.3 代码实现

3.3.1 方法一

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void leftround(char* arr, int len, int time)
{
	int tmp,i,j;
	//左旋次数
	time %= len;
	//左旋循环趟数
	for (i = 0; i < time; i++)
	{
		tmp = arr[0];//将第一个坐标对应的字符放到tmp空间
		for (j = 0; j < len - 1; j++)//j+1<4-->j<3
		{
			//后面的覆盖到前面
			arr[j] = arr[j + 1];
		}
		arr[j] = tmp;
	}
}
int main()
{
	char arr[] = "ABCD";
	int time = 0;
	scanf("%d\n", &time);
	int len = strlen(arr);
	leftround((char*)arr, len, time);
	printf("%s\n", arr);
	return 0;
}

3.3.2 优化一

3.3.2.1 思路分析

改进一:

这个思路当然可以,但是一次一次转毕竟太麻烦,就不能一次到位么?

当然可以,我们可以选择拼接法(需要借助库函数),一次到位:

我们先将移动k次之后的剩余的字符挪到tmp空间存放,再将移动k次涉及到的字符拷到tmp空间中刚刚字符的后面,最后拷到原数组中

 3.3.2.2 strcpy函数和strncat函数

3.3.2.3 代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void leftround(char* arr, int len, int time)
{
	//左旋次数
	time %= len;
	char tmp[200] = {0};
	strcpy(tmp, arr + time);//将不涉及左旋的字符全部拷到tmp
	strncat(tmp, arr, time);//将涉及到左旋的字符拼接到前面
	strcpy(arr, tmp);//最后拷回去原数组
}
int main()
{
	char arr[] = "ABCD";
	int time = 0;
	scanf("%d\n", &time);
	int len = strlen(arr);
	leftround((char*)arr, len, time);
	printf("%s\n", arr);
	return 0;
}

3.3.3 优化二

3.3.3.1 思路分析

改进二:

方法二要用到一个数组形成的辅助空间,让人觉得有点不爽,还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作方式:局部翻转

先将要左旋的前三个家伙逆序(翻转)ABCDEFG--->CBADEFG,然后将后半段也逆序(翻转)CBADEFG--->CBAGFED,最后整体逆序(翻转)CBAGEFD-->DEFGABC即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序

3.3.3.2 代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
void resrve_part(char* arr, int start, int end)
{
	//交换位置---翻转倒序
	while (start < end)
	{
		char tmp = arr[start];
		arr[start] = arr[end];
		arr[end] = tmp;
		start++;
		end--;
	}
}
void leftround(char* arr, int len, int time)
{
	//左旋次数
	time %= len;
	resrve_part(arr, 0, time - 1);//翻转前半部分
	resrve_part(arr, time, len-1);//翻转后半部分
	resrve_part(arr, 0, len-1);//全部翻转
}
int main()
{
	char arr[] = "ABCD";
	int time = 0;
	scanf("%d\n", &time);
	int len = strlen(arr);
	leftround((char*)arr, len, time);
	printf("%s\n", arr);
	return 0;
}


4.字符串旋转结果

4.1 题目

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1 =AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC

4.2 分析推理

本题最简单的思路就是可以将所有旋转后的结果放到一个数组里,然后进行查找:利用左旋的方法每左旋一次就去对比是否一样(共左旋len次,之后左旋结果重复


这里我们需要介绍一个用于比较不同的函数---strcmp函数

4.3 代码实现

4.3.1 方法一

#include<stdio.h>
#include<string.h>
int findnum(char* arr1, char* arr2, int len)
{
	int i, j, tmp;
	for (i = 0; i < len; i++)
	{
		tmp = arr1[0];
		for (j = 0; j < len - 1; j++)
		{
			arr1[j] = arr1[j + 1];
		}
		arr1[j] = tmp;
		if (strcmp(arr1, arr2) == 0)
		{
			return 1;
		}
	}
	return 0;
}
int main()
{
	char arr1[] = "AABCD";
	char arr2[] = "ABDCA";
	int len = strlen(arr1);
	int ret = findnum((char*)arr1, (char*)arr2, len);
	printf("%d", ret);
	return 0;
}

4.3.2 优化

4.3.2.1 思路分析

但是方法一这种做法既不好操作,也太费事,但是这题有一个很简单的做法---拼接法(借助库函数)

其实AABCD无论怎么旋,旋转后的所有结果,都包含在了AABCDAABCD这个字符串里了。

所以做法很简单,只需要将原字符串再来一遍接在后面,然后找一找待查找的字符串是不是两倍原字符串的子集即可。

但是我们需要借助库函数实现

4.3.2.2 strcat函数和strstr函数


4.3.2.3 代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int findnum(char* arr1, char* arr2)
{
	char tmp[200] = { 0 };
	strcpy(tmp, arr1);//初始化字符串拷到tmp
	strcat(tmp, arr1);//自己拼接自己
	return strstr(tmp, arr2) != NULL;//能否找到
}
int main()
{
	char arr1[] = "AABCD";
	char arr2[] = "DCBAA";
	int ret = findnum((char*)arr1, (char*)arr2);
	printf("%d", ret);
	return 0;
}

到这里,第二弹练习就结束了

PS:小江目前只是个新手小白。欢迎大家在评论区讨论哦!有问题也可以讨论的!

如果对你有帮助的话,记得点赞👍+收藏⭐️+关注➕

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/948757.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国产操作系统开放麒麟安装

国产操作系统 开放麒麟 银河麒麟 中科方德 统信UOS 红旗Linux 深度系统 优麒麟系统 开放麒麟操作系统 “开放麒麟1.0”是通过开放操作系统源代码的方式、由众多开发者共同参与研发的国产开源操作系统&#xff0c;系统的发布将有助于推动面向全场景的国产操作系统迭代更新&…

iOS 推送证书 Apple Push Services:不受信任的解决办法

2022年1月27日需要请求中间G4证书 ​​​​​​​ 链接 Apple PKI - Apple​​​​​​​

软件测试面试题:压测时,QPS一直上不去,如何排查?

在进行系统压测时&#xff0c;QPS&#xff08;Queries Per Second&#xff09;即每秒查询数&#xff0c;无法达到预期值是一个常见的问题&#xff0c;本文就来介绍下QPS一直上不去时应该如何排查。 一. 检查硬件资源 CPU使用率 使用top或nmon命令来查看CPU使用率。如果CPU使…

.netcore grpc日志记录配置

一、日志记录配置概述 通过配置文件appsettings.json进行配置通过Program.cs进行配置通过环境变量进行配置客户端通过日志通道进行配置 二、实战案例 配置环境变量:Logging__LogLevel__GrpcDebug配置Appsettings.json配置Program.cs配置客户端工厂以上截图是目前为止已知的可…

QT基础教程之六布局管理器和常用控件

QT基础教程之六布局管理器和常用控件 布局管理器 所谓 GUI 界面&#xff0c;归根结底&#xff0c;就是一堆组件的叠加。我们创建一个窗口&#xff0c;把按钮放上面&#xff0c;把图标放上面&#xff0c;这样就成了一个界面。在放置时&#xff0c;组件的位置尤其重要。我们必须…

C++ deque底层原理

deque底层原理 一、目的二、底层实现三、原理图四、类结构五、push_back六、pop_back 一、目的 实现双端数组 二、底层实现 双向开口的连续线性空间 三、原理图 四、类结构 class deque : protected Deque base _Deque_base._Deque_impl M_map 指针数组 _M_map_size …

java JUC并发编程 第五章 volatile与JMM

系列文章目录 第一章 java JUC并发编程 Future: link 第二章 java JUC并发编程 多线程锁: link 第三章 java JUC并发编程 中断机制: link 第四章 java JUC并发编程 java内存模型JMM: link 第五章 java JUC并发编程 volatile与JMM: link 文章目录 系列文章目录1 volatile 2大特…

KVM虚拟化ubuntu

KVM&#xff08;Kernel-based Virtual Machine&#xff09;是一种基于Linux内核的虚拟化技术&#xff0c;它将Linux内核作为虚拟机的底层操作系统&#xff0c;利用硬件虚拟化支持创建和管理虚拟机。KVM虚拟化技术被广泛应用于云计算、虚拟化服务器、虚拟化桌面等场景。 KVM虚拟…

最新无代码排名出炉,哪个平台最适合你?

随着无代码技术的迅速发展&#xff0c;国内外涌现出许多优秀的无代码平台提供商&#xff0c;企业在选择合适的无代码平台时可能会感到困惑&#xff0c;无从下手。为了帮助大家更好地了解国内真正的无代码平台厂商&#xff0c;本文将为您介绍几家具有代表性的厂商。 1.云表平台&…

数组中的第K个最大元素

题目链接 数组中的第K个最大元素 题目描述 注意点 需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素 解答思路 本题可以使用快速排序、堆排序或优先队列解决&#xff0c;快排可以比较快速找到某个元素在数组中排序后的位置&#xff0c;所以找…

Redis——》Redis的部署方式对分布式锁的影响

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

ToBeWritten之针对 Car ATTCK 的攻防矩阵

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 转移发布平台通知&#xff1a;将不再在CSDN博客发布新文章&#xff0c;敬…

有时间窗车辆路径问题(vehicle routing problems with time windows,VRPTW)学习实践与base案例代码开发

有时间窗车辆路径问题&#xff08;Vehicle Routing Problems with Time Windows&#xff0c;VRPTW&#xff09;是一类著名的组合优化问题&#xff0c;涉及在有限时间窗口约束下&#xff0c;有效地安排多个车辆的路径&#xff0c;以满足客户需求。 在VRPTW中&#xff0c;假设有…

what(): NCCL Error 1: unhandled cuda error解决方法

文章目录 遇到问题解决方法参考 遇到问题 运行项目&#xff1a;ACL2021的一篇工作&#xff0c;LM-BFF (Better Few-shot Fine-tuning of Language Models) https://github.com/princeton-nlp/LM-BFF 遇到环境问题。 我的机器环境如下&#xff1a; 服务器上CUDA版本为11.4 GPU…

为什么要参加浙大MPA提面申请?你看看AB资格的弃考率

时间即将来到九月份&#xff0c;在这个时间点依然能够坚持自己读研梦的考生&#xff0c;可以说基本是今年真正的准考生了&#xff01;在备考坚持这方面&#xff0c;其实每年很多考生走不到最后&#xff0c;比如在9-10月份全国研究生网上报名阶段&#xff0c;接近两成比例的考生…

geant4 常用代码

1 获取特特定能量范围的特定粒子 E:\examples_understanding\geant4-v11.0.0_note\examples\extended\runAndEvent\RE02 //-- Particle with kinetic energy filter.G4SDParticleWithEnergyFilter* pkinEFilter new G4SDParticleWithEnergyFilter(fltName"gammaE filter&…

招生大户!包邮区双非计算机强校计算机考研分析

杭州电子科技大学(B) 考研难度&#xff08;☆☆&#xff09; 内容&#xff1a;23考情概况&#xff08;拟录取和复试分析&#xff09;、院校概况、23初试科目、23复试详情、各专业考情分析、各科目考情分析。 正文1689字&#xff0c;多表&#xff0c;预计阅读&#xff1a;5分钟…

Python中小数据池知识最详细教程

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说&#xff0c;直接开搞&#xff0c;如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 一、id&#xff0c;is&#xff0c; 在Python中&#xff0c;id是什么&#xff1f; id是内存地址&#xff0c;比如你利用i…

centos升级python

升级为python3.10 yum updateyum install openssl-devel bzip2-devel libffi-develyum groupinstall "Development Tools"wget https://www.python.org/ftp/python/3.10.2/Python-3.10.2.tgztar -xzf Python-3.10.2.tgzcd Python-3.10.2./configure --enable-optimi…

JavaScript常见的运算符

一、运算符和运算元 1.认识运算符 在小学的时候我们就学习了各种运算符&#xff0c;比如加号 、乘号 *、减号 - 、除号/ 几乎所有的编程语言都有各种各样的运算符(也被称之为操作符&#xff0c;operators) 初次接触这些运算符, 你会感觉种类繁多, 难以记忆.但是并不需要特别…