文章目录

  • 1. 找单身狗
    • 思路
    • 代码
  • 2. 模拟实现atoi
    • 思路
    • 代码
  • 3. 实现offsetof宏
    • 思路
    • 代码
  • 4. 交换奇偶位
    • 思路
    • 代码

1. 找单身狗

思路

要找出不同的数首先想到异或,由于异或的性质,相同的数异或为0,0异或任何数等于本身,
因此可以使用异或解决这题:
联想到如果只有一个数出现一次,那么将这组数全部异异或一遍最后的结果就是出现一次的数,这题有两个数出现了一次,所以可以将这一组数分成两组,每组都是只有一个数出现一次,每一组的元素全部异或,最后2组的2个结果就是只出现一次的两个数
分割线---------------------------------------------------------------------------------
关键问题变成了通过什么条件能够成功将这两个数分在不同组,所以我们需要找到能够区别这两个数的一个标记,有没有很熟悉?什么可以区别2个数,什么操作符专门为区别而生?什么操作符专门为找不同而生?没错,它就是异或
如果两个数的对应的某个二进制位异或为1,那么这两个数对应的位肯定一个是0,另一个是1,于是我们就可以通过根据这一位来分组,这一位为0的在一组,这一位为1的在另一组,于是就有以下代码

代码

//找出两个只出现一次的数字
#include <stdio.h>
/// <summary>
/// res用来接受两个单身狗
/// n是两个单身狗的异或
/// pos用来表示两个单身狗不同的位
/// </summary>
/// <param name="arr"></param>
/// <param name="sz"></param>
void FindArr(int* arr, int sz)
{int res[2] = {0};int n = arr[0];int pos = 0;//得到两个单身狗的异或for (int i = 1; i < sz; i++){n ^= arr[i];}//找到异或结果为1的位for (int i = 0; i < 32; i++){if (1 == ((n >> i) & 1)){pos = i;break;}}//根据两个单身狗的pos位不同分组,每组分别异或for (int i = 0; i < sz; i++){if (1 == ((arr[i] >> pos) & 1)) res[0] ^= arr[i];else res[1] ^= arr[i];}printf("单身狗->%d\n单生狗->%d", res[0], res[1]);
}
int main()
{int arr[] = { 1,2,3,4, 5,1,2,3, 4, 6 };FindArr(arr, sizeof(arr) / sizeof(int));return 0;
}

2. 模拟实现atoi

atoi函数介绍

  • atoi函数的功能是将字符串转换为整数
  • 首先丢弃最开始的空白,直到找到第一个数字字符
  • 如果第一个非空白字符不是数字字符也不是’+‘’'-,返回结果为0
  • 第一个非空白字符是’-'表示返回的是负数
  • 该字符串可以在构成整数的字符之后包含其他字符,这些字符将被忽略并且对此函数的行为没有影响。

思路

由于atoi函数转化失败会返回0,转换成功也有可能返回0,因此为了区分0是失败产生的还是成功产生的,定义枚举常量来体现失败还是成成功
不合法的情况有以下几种

  1. 转入的是空串
  2. 第一个非空白字符不是符号位或整数字符
  3. 符号位后的字符不是整数字符
  4. 转换的结果超出了int 所表示的范围

代码

//模拟atoi
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
enum State
{VALID,UNVALID
};
enum State state = 0;//开始默认合法int Atoi(const char* str, char* result)
{assert(str);//传入空串if (*str == '\0'){state = 1;strcpy(result, "传入的是空字符串");return 0;}int len = strlen(str);int i = 0;long long res = 0;int sign = 1;while (isspace(str[i])) i++; //找到第一个非空白字符//第一个非空白字符不合法if (str[i] != '+' && str[i] != '-' && !isdigit(str[i])){state = 1;strcpy(result, "第一个非空白字符不合法");return 0; }//判断正负if (str[i++] == '-') sign *= -1; //符号位后的字符不是数字字符if (!isdigit(str[i])){state = 1;strcpy(result, "符号位后的字符不合法");return 0;}//找到第一个非数字字符while (isdigit(str[i]) && str[i] != '\0'){if (res > INT_MAX){//结果超出INT所表示的范围state = 1;strcpy(result, "转换结果超出了INT的范围");return 0;}res = 10 * res + str[i] - '0';i++;}return sign * res;
}int main()
{char str[100];//记录失败的原因char result[100];fgets(str, 100, stdin);int n = Atoi(str, result);if (state == 1){printf("转换失败->%s\n", result);}else{printf("转换成功->%d\n", n);}return 0;
}

3. 实现offsetof宏

  • 这个函数形式的宏返回成员成员在数据结构或联合类型类型中以字节为单位的偏移值。

思路


想要求出某个成员的偏移量,可以用该成员的地址减去结构体变量的起始地址,由于实现的是一个宏,没法直到结构体变量的地址,因此关键在于如何知道结构体变量的地址
我们虽然不知道结构体变量的地址,但是我们可以假设结构体变量在地址为0处,这样的话该结构体某个成员的地址就是该成员的偏移量

代码

//写一个宏,实现offsetof
#include <stdio.h>
//宏的特点,不在乎参数的类型
//假设0处的地址为该结构体类型的地址,通过->和&找到所求偏移量的成员地址,将地址强转为uint类型
#define OFFSETOF(type, number)  (size_t)(&(((type*)0)->number))
struct People
{int age;double weight;
};
int main()
{printf("age->%d\nweight->%d\n",OFFSETOF(struct People, age), OFFSETOF(struct People, weight));return 0;
}

注意:在这个特定的用例中,->实际上是用来计算结构体或类成员的偏移量的语法,而不是用来解引用一个指针的语法,因此不会出现解引用空指针这个问题


4. 交换奇偶位

思路

交换相邻的奇偶位一共三步

  1. 取出所有奇数位(偶数位为0),左移一位使得奇数位在偶数位上
  2. 取出所有偶数位(奇数位为0),右移一位使得偶数位在奇数位上
  3. 将1、2的结果相加

1中另偶数位为0的目的就是为了相加后偶数位恰好是原来的奇数位,2中同理

代码

#include <stdio.h>
//&0xaaaaaaaa可以保留偶数位并且另奇数位为0
//&0x55555555可以保留奇数位并且另偶数位为0
#define SWAP_BITS(x) x = (((x) & 0xaaaaaaaa) >> 1) + (((x) & 0x55555555) << 1)
int main()
{unsigned int n = 5;SWAP_BITS(n);printf("%u\n", n);
}

tips:

  • 可以将+替换成|
  • 如果要交换long long 类型数据,需要用0xaaaaaaaaaaaaaaaa替换0xaaaaaaaa,0x5555555555555555替换0x55555555

找单生狗,模拟atoi,模拟offsetof,交换奇偶位相关推荐

  1. 2021年高压电工找解析及高压电工作业模拟考试

    题库来源:安全生产模拟考试一点通公众号小程序 高压电工找解析是安全生产模拟考试一点通总题库中生成的一套高压电工作业模拟考试,安全生产模拟考试一点通上高压电工作业手机同步练习.2021年高压电工找解析及 ...

  2. 2021年化工自动化控制仪表找解析及化工自动化控制仪表模拟考试题库

    题库来源:安全生产模拟考试一点通公众号小程序 安全生产模拟考试一点通:化工自动化控制仪表找解析是安全生产模拟考试一点通总题库中生成的一套化工自动化控制仪表模拟考试题库,安全生产模拟考试一点通上化工自动 ...

  3. C++面经之应届生找工作的“狗日”过程记录

    C++面经之应届生找工作的"狗日"过程记录 .先附上我的座右铭: "不是因为看到希望才去坚持,而是坚持才会有希望." . 吐槽一下: 2020注定是个苦逼年,坐 ...

  4. STM32模拟SPI时序控制双路16位数模转换(16bit DAC)芯片DAC8552电压输出

    STM32模拟SPI时序控制双路16位数模转换(16bit DAC)芯片DAC8552电压输出 STM32部分芯片具有12位DAC输出能力,要实现16位及以上DAC输出需要外挂DAC转换ASIC. D ...

  5. 社恐人必备逃跑神器-模拟来电+模拟短信+模拟钱包+模拟关机

    小伙伴们注意:公众号的推送机制不再按照时间前后推送了,微信公众号信息流乱序.君哥建议大家把科技毒瘤君公众号置顶(设为星标⭐),以便第一时间看到推送,非常感谢~,方法如下图: 如果你是一个具有社交恐惧症 ...

  6. 驱动级模拟驱动级模拟:直接读写键盘的硬件端口!

    驱动级模拟驱动级模拟:直接读写键盘的硬件端口! 有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的 ...

  7. lammps计算聚合物例子_LAMMPS模拟聚合物结构,非晶态聚合物变形行为的模拟,纳米线变形模拟,单轴张力模拟,晶格参数计算...

    推荐一个网站,上面有LAMMPS模拟聚合物结构,非晶态聚合物变形行为的模拟,纳米线变形模拟,单轴张力模拟,晶格参数计算的lammps脚本,如下面是晶格参数计算的lammps脚本,具体网址是: LAMM ...

  8. 村子里有50个人,每人有一条狗,在这50条狗中有病狗(这种病不传染),于是人们要找出病狗。

    IBM公司向来以高素质人才作为企业持续竞争力的保证.进入IBM公司是差不多每个IT人的梦想.下面这条IBM公司的面试题,给大家试试看,看看是否具备进入IBM的实力! 村子里有50个人,每人有一条狗,在 ...

  9. 计算机CCT考试模拟操作题,基础计算机cct模拟测试模拟题.doc

    基础计算机cct模拟测试模拟题 一.单选 1. 用计算机进行图书资料的检索,该计算机应用属于 A. 数据处理 B. 自动控制 C. 辅助设计 D. 科学计算 8. 下列图标不会出现在"控制面 ...

最新文章

  1. FTP(虚拟用户,并且每个虚拟用户可以具有独立的属性配置)
  2. 域服务器广播消息,广播,组播和UNIX域套接字
  3. HDU5511 : Minimum Cut-Cut
  4. mysql集群数据引擎_MySQL数据引擎
  5. PhpStorm 配置Xdebug
  6. JBPM学习笔记(1)
  7. ftl不存在为真_FreeMarker 处理不存在的变量
  8. 要想提高工作效率,请拒绝做这7种事
  9. 科个普:进程、线程、并发、并行
  10. kvm迁移镜像启动报错(the CPU is incompatible with host CPU: Host CPU does not provide required features: fma)
  11. [转载] python3 numpy函数_Python numpy总结(3)——常用函数用法
  12. tomcat实现多端口、多域名访问(只针对一个tomcat)
  13. web文件操作常见安全漏洞(目录、文件名检测漏洞)
  14. 前端两种播放视频的方式
  15. linux系统查看内核版本是多少,在linux下查看内核版本、gcc版本、操作系统多少位等参数...
  16. 2022-2027年(新版)中国产权交易行业前景动态与未来发展形势报告
  17. 多功能流媒体播放器实现网页无插件直播之EasyPlayer.js如何实现播放完自动循环播放
  18. Git操作与仓库创建
  19. 查找字幕资源的网址。射手网
  20. SuSE and NLD9 user pls note

热门文章

  1. 安利这款软件给专注不下来的你
  2. 基于 Transformer 模型的电影评论情感分类
  3. 如何快速开设海外银行账户
  4. 使用MultiPowerOnOffTool工具 测试拔插网线对路由器的影响
  5. 锤子手机T1发布:售价3000元起 7月初上市
  6. 小新想把百度搜索引擎改为edge
  7. SATA、mSATA、M.2、M.2(NVMe)、PCIE固态硬盘接口详解
  8. 查看思科交换机出厂时间
  9. 【Unity】雷达 + 照片墙效果
  10. 自己写Shader-翻书效果