【C语言练习】——找出单身狗、详解atoi函数

news2024/11/24 17:44:55

目录

    • 一.找出单身狗
      • 版本1
      • 版本2
    • 二.atoi函数
      • 介绍atoi函数
      • atoi函数的模拟实现

一.找出单身狗

版本1

题目:
一个数组中只有一个数字是出现一次,其他所有数字都出现了两次
找出这一个只出现一次的数字

一个数组比如是1、2、3、4、5、1、2、3、4
只有5出现一次,其他数字都是成对出现的,所以5就是单身狗。

思路:异或法
这里给大家回顾下异或:相同为0,相异为1

比如:
a ^ a = 0
a ^ 0 = a

异或是支持交换律的,用具体数字举例:3 ^ 5 ^ 3

3的二进制是011
5的二进制是101
异或的结果是110
再和3异或
得到的是101——数字5

3 ^ 3 ^ 5

3和3异或是0
0和5异或是5

所以回到前面举例的数组

1、2、3、4、5、1、2、3、4

也等价于:

1、1、2、2、3、3、4、4、5

前面成对出现的数字都异或为0(0异或0还是0),0与唯一出现的数字异或就是这个数字,也就是单身狗

代码:

int F_S_dog1(int arr[], int sz)
{
	int ret = 0;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		ret ^= arr[i];
	}
	return ret;
}
int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int dog = F_S_dog1(arr, sz);
	printf("%d\n", dog);
	return 0;
}

版本2

题目:
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次
找出这两个只出现一次的数字

一个数组比如是1、2、3、4、5、6、1、2、3、4
只有5和6出现一次,其他数字都是成对出现的,所以5和6就是单身狗。

思路:

  1. 将数组进行分组处理,每组有一个单身狗,其他数字成对出现
  2. 成对的数字在同一组里,然后采用异或法找出单身狗

比如分组后为:

1、1、3、3、5
2、2、4、4、6

那么任何进行分组呢?
首先,用版本1的思路我们可以先对原数据进行异或处理,就可以找到那两个是单身狗的数字

1 ^ 1 ^ 2 ^ 2 ^ 3 ^ 3 ^ 4 ^ 4 ^ 5 ^ 6 = 5 ^ 6

5和6异或的结果一定不为0

5的二进制是101
6的二进制是110
异或为011

也就是说5和6异或的结果的二进制后面两位是不同的

以最低位为例,5的最低位是1,6的最低位是0,那么分组就可以根据最低位来判断

1的最低位是1,2的最低位是0,
3的最低位是1,4的最低位是0,
分组后:
1、1、3、3、5
2、2、4、4、6

假如不是5和6,是6和8,最低位相同,那么可以用前面一位比较,方法同上

但不管怎么分,都可以把两个单身狗数字分到不同的组

第二步,找出两个数异或的结果第几位不同
还是前面的两个数字5和6,异或的结果为011,后面两位不同。为了方便起见,使用一个变量(pos)记录最低位不同是移动了几位,移动pos位按位与得到是1就说明两个数字二进制的这一位不同(也就是1,因为1按位与1得到的是1),然后跳出循环。

最后一步,正式开始分组,然后还是异或法找到单身狗
数组的每个元素移动pos位,把移动pos按位与相同的数字放在同一组,然后异或法找到单身狗

当然,只是找到其中一个单身狗,另一个单身狗就是两个单身狗异或的结果再异或前面已经找到的单身狗

代码:

void F_S_dog2(int arr[], int sz, int* pd1, int* pd2)
{
	int ret = 0;
	int i = 0;
	//找到两个唯一的数
	for (i = 0; i < sz; i++)
	{
		ret ^= arr[i];
	}
	int pos = 0;
	//找到第几位不同
	for (i = 0; i < 32; i++)
	{
		if ((ret >> i & 1) == 1)
		{
			pos = i;
			break;
		}
	}
	//分组
	for (i = 0; i < sz; i++)
	{
		if ((arr[i] >> pos & 1) == 1)
		{
			*pd1 ^= arr[i];
		}
	}
	*pd2 = ret ^ *pd1;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,1,2,3,4 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int dog1 = 0;
	int dog2 = 0;
	F_S_dog2(arr, sz, &dog1, &dog2);
	printf("%d %d", dog1, dog2);
	return 0;
}

二.atoi函数

介绍atoi函数

atoi函数的作用是将字符串转换成整数

int atoi (const char * str);

该函数有以下几点要注意
在这里插入图片描述

1.返回值为int 类型的整数,不能超出int 表示的范围
2.该函数首先根据需要丢弃尽可能多的空格字符(如 isspace) ,直到找到第一个非空格字符。然后,从这个字符开始,取一个可选的初始正负号,后跟尽可能多的十进制数字,并返回一个数值
3.字符串可以在构成整数的字符之后包含其他字符,这些字符将被忽略
4.如果 str 中的第一个非空格字符序列不是一个有效的整数,或者由于 str 为空或者它只包含空格字符而不存在这样的序列,则不执行转换并返回零

代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int ret = atoi("-456");
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

atoi函数的模拟实现

首先要考虑几个问题:

1.传过来的字符串是否为空指针
2.是否为空字符串
3.有空格字符怎么办
4.遇到正负号
5.是否为数字字符
6.数值太大

接下来一个一个解决问题:

1.传过来的字符串是否为空指针
可以用assert进行断言,防止为空

assert(str);

2.是否为空字符串
加个判断条件,如果为’ \0 ',就返回0

    if (*str == '\0')
	{
		return 0;
	}

3.有空格字符怎么办
使用isspace函数判断是否有空格字符,如果有,向后走一步

    while (isspace(*str))
	{
		str++;
	}

4.遇到正负号
在此之前定义一个变量flag为1,如果遇到 ’ - ',flag=-1,向后走一步;遇到 ’ + ’ ,向后走一步。

    if (*str == '-')
	{
		flag = -1;
		str++;
	}
	else if (*str == '+')
	{
		str++;
	}

5.是否为数字字符 && 6.数值太大
使用isdigit函数判断是否为数字字符,如果不是,也就是说刚开始就遇到其他字符或者在中途遇到其他字符,就直接返回前面的数字字符;如果是数字字符,每次循环的值等于上次的值乘以10再加上数字字符减去字符0,得到整数。
还要加上一个判断,如果要返回的值超过int 类型的范围,说明返回值为异常,直接返回0。

    long long ret = 0;
	while (*str)
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			if (ret<INT_MIN || ret>INT_MAX)
			{
				return 0;
			}
		}
		else
		{
			return (int)ret;
		}
		str++;
	}

最后的返回值处理
定义一个枚举,如果是VALID,标记为是正常的返回值,是INVALID,标记为异常的返回值。同时给个全局变量State,只有最后让State等于VALID,就说明返回的是正常的值,其他的则为异常。

enum State
{
	VALID,
	INVALID
}State = INVALID;//全局变量判断是否为异常的返回值
	State = VALID;
	return (int)ret;

代码:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
enum State
{
	VALID,
	INVALID
}State = INVALID;//全局变量判断是否为异常的返回值
int my_atoi(const char* str)
{
	int flag = 1;
	//判断空指针
	assert(str);
	//判断空字符串
	if (*str == '\0')
	{
		return 0;
	}
	//判断空格字符
	while (isspace(*str))
	{
		str++;
	}
	//遇到正负号
	if (*str == '-')
	{
		flag = -1;
		str++;
	}
	else if (*str == '+')
	{
		str++;
	}
	//返回整数值,遇到其他字符直接返回
	long long ret = 0;
	while (*str)
	{
		if (isdigit(*str))
		{
			ret = ret * 10 + flag * (*str - '0');
			if (ret<INT_MIN || ret>INT_MAX)
			{
				return 0;
			}
		}
		else
		{
			return (int)ret;
		}
		str++;
	}
	//正常返回
	State = VALID;
	return (int)ret;
}
int main()
{
	int ret = my_atoi("   -456ab21");
	if (State == VALID)
	{
		printf("%d\n", ret);
	}
	else
	{
		printf("异常返回:%d\n", ret);
	}
	return 0;
}

在这里插入图片描述

感谢观看~
在这里插入图片描述

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

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

相关文章

【力扣每日一题】2023.8.13 合并两个有序数组

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们两个升序数组&#xff0c;让我们合并它们&#xff0c;要求合并之后仍然是升序&#xff0c;并且这个合并操作是在数组1原地修改…

前沿分享-中距离射频取电

目前来看&#xff0c;微能源有四种技术路线&#xff0c;一是环境光采集、温差转换采集、无线射频采集和振动能量采集。 无线射频微能源是在通信设备通信过程中自然产生的&#xff0c;可以通过射频能量芯片实现无线射频取电&#xff0c;能瞬间大功率储电和安全驱动负载。 通过射…

基于微信小程序的应届大学生招聘平台的设计与实现

伴随着社会以及科学技术的发展&#xff0c;互联网已经渗透在人们的身边&#xff0c;网络慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着众多智能手机飞速的发展&#xff0c;小程序这一名词已不陌生&#xff0c;越来越多的企业、公司、高校、医院等机构都会使用小程…

Linux上的五种IO模型

文章目录 五种模型阻塞非阻塞IO复用信号驱动异步 五种模型 阻塞非阻塞复用IO异步 阻塞 &#x1f446;read同步IO 非阻塞 EAGAIN&#xff1a;没有事件到达&#xff0c;返回值为-1&#xff0c; errno为EAGAIN IO复用 信号驱动 异步 &#x1f446;&#xff1a;异步IO&#xff…

Leetcode数组篇 Day1

移除元素&#xff08;暴力版&#xff09; 1.注意越界问题&#xff1a;ji1 起点&#xff0c;j < size 移除元素&#xff08;双指针版&#xff09; 1.快慢指针&#xff0c;新数组就是不含有目标元素的数组 快&#xff1a;获取新数组中的元素 慢&#xff1a;获取新数组需更新位…

【佳佳怪文献分享】通过跨模态监督学习视觉运动

标题&#xff1a;Learning Visual Locomotion with Cross-Modal Supervision 作者&#xff1a;Antonio Loquercio, Ashish Kumar, Jitendra Malik 来源&#xff1a;2023 IEEE International Conference on Robotics and Automation (ICRA 2023) 这是佳佳怪分享的第4篇文章 …

电视企业继续乱收费,消费者则再用脚投票,销量加速下滑

分析机构给出的7月份数据显示中国的电视销量同比下滑了14.1%&#xff0c;环比则下滑了23.4%&#xff0c;消费者继续用脚投票&#xff0c;而电视企业也在压榨最后一滴利润&#xff0c;继续乱收费&#xff0c;引发消费者的不满。 近几年来国内电视市场价格战异常激烈&#xff0c;…

手把手教你使用USB的CDC+MSC复合设备(基于stm32f407)

学习 1 实验环境与说明2 USB CDC2.1 CDC代码生成2.2 通信设备&#xff08;CDC&#xff09;描述符2.2.1 设备描述符2.2.2 配置描述符 2.3 调试 3 USB MSC3.1 MSC代码生成3.2 大容量存储设备&#xff08;MSC&#xff09;描述符3.2.1 设备描述符2.2.2 配置描述符 3.3 调试 4 USB复…

Redis_亿级访问量数据处理

11. 亿级访问量数据处理 11.1 场景表述 手机APP用户登录信息&#xff0c;一天用户登录ID或设备ID电商或者美团平台&#xff0c;一个商品对应的评论文章对应的评论APP上有打卡信息网站上访问量统计统计新增用户第二天还留存商品评论的排序月活统计统计独立访客(Unique Vistito…

LeetCode150道面试经典题--单词规律(简单)

1.题目 给定一种规律 pattern 和一个字符串 s &#xff0c;判断 s 是否遵循相同的规律。 这里的 遵循 指完全匹配&#xff0c;例如&#xff0c; pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。 2.示例 pattern"abba" s "c…

【java】基础——多态

多态基本知识思维导图 多态的代码实现&#xff0c;注意父类对象引用指向子类对象引用&#xff08;向上转型&#xff09;的方法&#xff0c;父类就可以调用子类重写的方法和派生的方法&#xff0c;但不能调用子类特有的方法&#xff1a; class Animal {public void makeSound()…

基于模型的术语定义

文章仅供个人学习使用&#xff0c;请勿传播&#xff01; 原文来源&#xff1a; 袁亦方 大易方圆 OPM对象过程方法 2023-08-13 07:01 https://mp.weixin.qq.com/s/dUtuNLrMwFF_foCrQQyWmA INCOSE系统工程手册第5版使用说明部分&#xff08;内容对应第4版1.5节&#xff09;提出&…

MySQL高阶知识点(一)一条SQL【更新】语句是如何执行的

一条SQL【更新】语句是如何执行的 首先&#xff0c;可以确定的说&#xff0c;【查询】语句的那一套流程&#xff0c;【更新】语句也是同样会走一遍&#xff0c;与查询流程不一样的是&#xff0c; 更新语句涉及到【事务】&#xff0c;就必须保证事务的四大特性&#xff1a;ACID&…

vite打包报错

先把报错信息附上 解决&#xff1a; 在报错的文件里加上ts就可以了

Python python文件打包exe文件

首先安装PyInstaller&#xff0c;在PyCharm终端窗口输入命令&#xff1a; pip install PyInstaller安装完成后&#xff0c;在输入命令&#xff1a; pyinstaller -F /Users/sunshiyu/Desktop/PYTHON/demo1.pydemo1.py是我创建的一个简单的Python文件&#xff0c;代码如下&#x…

数据结构:堆的应用(堆排序和topk问题)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》 文章目录 堆排序建堆堆的删除思想排序代码实现 top k 问题思路代码实现 总结 堆排序 堆排序即是 先将数据建堆&#xff0c;再利用堆删除的思想来排序。 将待排序数组建堆将堆顶数据与数组尾部数…

【python】爬取豆瓣电影Top250(附源码)

前言 在网络爬虫的开发过程中&#xff0c;经常会遇到需要处理一些反爬机制的情况。其中之一就是网站对于频繁访问的限制&#xff0c;即IP封禁。为了绕过这种限制&#xff0c;我们可以使用代理IP来动态改变请求的来源IP地址。在本篇博客中&#xff0c;将介绍如何使用代理IP的技术…

RHEL 7配置HAProxy实现Web负载均衡

一、测试环境HAProxy&#xff1a; 主机名&#xff1a;RH7-HAProxy IP地址&#xff1a;192.168.10.20 操作系统&#xff1a;Red Hat Enterprise Linux Server release 7.2 (Maipo)最小化安装 防火墙与SELinux&#xff1a;关闭 安装的服务&#xff1a;HAProxy-1.5.14 WEB01: 主…

[管理与领导-12]:IT基层管理者 - 绩效面谈 - 如何面谈,遇到问题员工怎么办?

目录 前言&#xff1a; 第1章 问题现象 第一&#xff1a;面谈没效果 第二&#xff1a;问题没解决 第三&#xff1a;双方都不满 第2章 背后原因 1.1 面谈变成了训话&#xff1a;引导变成训话 1.2 面谈变成了扯皮&#xff1a;立足未来变成纠缠过去 1.3 面谈变成了双方较…

vite4+vue3:从0到1搭建vben后台管理系统(五)-封装属于自己的form组件

日常业务开发中的,避免不了的要接触到表单开发,那么我们有必要了解表单的深入使用方法,及封装出适合自己业务的自定义表单组件,效果如下: 不是用ele和antdvue框架,实现自己的表单组件!!! ValidateForm组件封装 <template><div class="validate-form…