C:每日一练:单身狗(2.0版本)

5703a68c899f40cd85d54a77087f8f5f.gif

前言:

今天在刷题的时候突然看到一道题,疑似一位故题。仔细一看,欸!这不是就是单身狗的升级版吗?我想那必须再安排一篇,不过由于本篇文章与上一篇单身狗文章所涉及的知识点基本相同,所以还请大家见谅!

我写的开心,大家也看个乐呵!不过还请单身的人不要介意,单纯觉得比较有意思,无意冒犯!毕竟连小编自己都是单身狗。

后续小编也会尽快更新完指针相关知识点!

一、题目:

在一场专为情侣们策划的盛宴中,竟然有两名单身者悄然混入。宴会的主人感到十分不悦,并寻求你的帮助,希望你能运用你敏锐的洞察力,协助她识破并找出这两名不合规矩的单身者。

(无意冒犯,只是提供一个题目的背景)

例如:

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

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

二、代码展示(无注释的)

如果有想先自己思考的可以先看一看这个代码,后面也会有解析

#include <stdio.h>
int find(int num) {int index = 0;while ((num & 1) == 0 && index < 32) {num >>= 1;index++;}return index;
}
void single(int arr[], int sz, int* n1, int* n2) {int Re = 0;for (int i = 0; i < sz; i++) {Re ^= arr[i];}int index = find(Re);*n1 = *n2 = 0;for (int i = 0; i < sz; i++) {if (((arr[i] >> index) & 1) == 1) *n1 ^= arr[i];    else *n2 ^= arr[i];}
int main() {int arr[] = {1,2,3,4,5,6,1,2,3,4,5,7};int n1, n2;int sz = sizeof(arr) / sizeof(arr[0]);single(arr, sz, &n1, &n2);printf("两只单身狗分别是:%d 和 %d\n", n1, n2);return 0;
}

三、题解思路:

1.关于算法,我们依然使用的是异或运算,因为异或运算相同为0,所以将数组中所有的数字进行异或操作,最终得到的结果就是那两个只出现一次的数字的异或值。

例如:

举个例子: int arr[ ] = {1,1,2}

初始re = 0;

re = re ^ 1 = 1;此时re = 1;

re = re ^ 1 = 1 ^ 1 = 0;此时re = 0;

re = re ^ 2 = 0 ^ 2 = 2;此时re = 2;所以只出现一次的数字是2

2.找到这个异或结果中为 1 的某一位。根据异或运算不同为1,这一位为 1 说明在这一位上,那两个只出现一次的数字是不同的。

例如:数组{1,1,2}
异或运算:1^1^2 = 2;
0010   2的二进制
 异或的结果是0010,从右向左找1的位置
0000   0的二进制
0010   2的二进制
0000^0010 = 0010 (异或运算相同为0,不同为1)
我们可以发现0在这一位上的数字是0,2在这一位上的数字是2,说明结果为1的这一位,两个只出现一次的数字是不同的。

3.根据这一位将数组中的数字分为两组。一组是这一位为 1 的数字,另一组是这一位为 0 的数字。

再对这两组数字分别进行异或操作,就可以得到那两个只出现一次的数字。

例如,数组为{1,2,3,1,2,4}

第一步,将所有数字异或:1 ^ 2 ^ 3 ^ 1 ^ 2 ^ 4=7(二进制为0111 )

第二步,找到异或结果中为 1 的一位,从右往左数第一位为 1 

第三步,根据这一位将数字分组:

  • 这一位为 1 的数字:{3,4}
  • 这一位为 0 的数字:{1,2,1,2}

四、函数介绍

1.main函数

int main() 
{int arr[] = {1,2,3,4,5,6,1,2,3,4,5,7};int n1, n2;int sz = sizeof(arr) / sizeof(arr[0]);single(arr, sz, &n1, &n2);printf("两只单身狗分别是:%d 和 %d\n", n1, n2);return 0;
}
  •  数组的输入:int arr[] = {1,2,3,4,5,6,1,2,3,4,5,7};
  • 数组元素个数计算: int sz = sizeof(arr) / sizeof(arr[0]);
  • 调用函数: single(arr, sz, &n1, &n2);

2.single函数

void single(int arr[], int sz, int* n1, int* n2) {int Re = 0;for (int i = 0; i < sz; i++) {Re ^= arr[i];}int index = find(Re);*n1 = *n2 = 0;for (int i = 0; i < sz; i++) {if (((arr[i] >> index) & 1) == 1) {*n1 ^= arr[i];}else {*n2 ^= arr[i];}}
}

single函数作用:找出数组中两个只出现一次的数字

第一个for循环实现数组中所有元素的异或运算

第二个for循环用于根据索引值,将数组分为两组并分别进行异或运算

 int index = find(Re);将索引值传给find函数

3.find函数

int find(int num) {int index = 0;while ((num & 1) == 0 && index < 32) {num >>= 1;index++;}return index;
}

 find函数用于找到一个数的二进制表示中从右往左第一个为 1 的位的索引

五:代码展示(含注释)

#include <stdio.h>
int find(int num)int index = 0;while ((num & 1) == 0 && index < 32)  // 当前二进制位为 0 并且索引小于 32{num >>= 1;//实现二进制中每位检查index++;}return index;// 返回第一个结果为 1 的位的索引
}
void single(int arr[], int sz, int* n1, int* n2) int Re = 0;// 对数组中所有数字进行异或操作,得到两个只出现一次数字的异或结果for (int i = 0; i < sz; i++) {Re ^= arr[i];}int index = find(Re);// 找到上述异或结果中第一个为 1 的位的索引*n1 = *n2 = 0;// 根据找到的索引位,将数组数字分为两组并分别异或for (int i = 0; i < sz; i++) {if (((arr[i] >> index) & 1) == 1) // 判断当前数字在指定索引位是否为 1*n1 ^= arr[i];   else *n2 ^= arr[i];  }
}
int main() 
{int arr[] = { 1, 2, 3, 2, 1, 4 };int n1, n2;int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素single(arr, sz, &n1, &n2);//函数调用printf("两只单身狗分别是:%d 和 %d\n", n1, n2);return 0;
}

 d7715019c6ad4dd5ac0c518fc65d2eed.gif

 

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

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

相关文章

流媒体服务器二:2.RTMP协议学习

RTMP协议详解 一.总体介绍 RTMP协议是应⽤层协议&#xff0c;是要靠底层可靠的传输层协议&#xff08;通常是TCP&#xff09;来保证信息传输的可靠性的。在 基于传输层协议的链接建⽴完成后&#xff0c;RTMP协议也要客户端和服务器通过“握⼿”来建⽴基于传输层链接之 上的RT…

滴滴开源新项目Unify:聚焦Flutter与原生通信难题,助力跨端应用落地

引言 在移动开发领域&#xff0c;移动跨端技术因其提效收益&#xff0c;逐渐成为业界趋势之一。Flutter 作为近年来热门的跨端技术&#xff0c;以高性能、自渲染、泛跨端著称&#xff0c;得到广泛应用。在滴滴国际化业务中&#xff0c;我们大量应用 Flutter。目前已在滴滴国际化…

C语言-使用数组法,指针法实现将一个5X5的矩阵中最大的元素放在中心,四个角分别放四个最小的元素(顺序为从左到右,从上到下,从小到大存放),写一函数实现之。

1.题目要求&#xff1a; 将一个5X5的矩阵中最大的元素放在中心&#xff0c;四个角分别放四个最小的元素&#xff08;顺序为从左到右&#xff0c;从上到下&#xff0c;从小到大存放&#xff09;&#xff0c;写一函数实现之。 2.数组法实现 #define _CRT_SECURE_NO_WARNINGS 1…

python从入门到精通:数据容器

数据容器介绍 一种可以容纳多份数据的数据类型&#xff0c;容纳的每一份数据称之为一个元素&#xff0c;可以是任意类型的数据&#xff0c;如字符串、数字、布尔等。 数据容器根据特点的不同&#xff0c;如&#xff1a; 是否支持重复元素 是否可以修改 是否有序&#xff0…

数据库根据日期统计SQL编写记录

统计每天产生多少数据 SELECT to_char("日期字段",YYYY-MM-dd) time ,count(*) FROM "表名" GROUP BY time;统计每月产生多少数据 SELECT to_char("日期字段",YYYY-MM) time ,count(*) FROM "表名" GROUP BY time;统计每年产生多少数…

【GitLab】使用 Docker 安装 GitLab 1:配置 SSH 端口

使用 Docker 安装 GitLab 要求修改ssh端口 GitLab 使用 SSH 通过 SSH 与 Git 交互。默认情况下,GitLab 使用端口22。 要在使用 GitLab Docker 映像时使用其他端口,您可以执行以下操作之一: 更改服务器的 SSH 端口(推荐)。 更改 GitLab Shell SSH 端口。 更改服务器的 SSH …

C++(week17): C++提高:(七)workflow

文章目录 一、Http协议二、Nginx1.概念2.nginx的安装和部署(1)安装nginx(2)使用nginx服务器部署静态资源 3.HTTP服务器架构(1)基于进程、基于线程&#xff1a;APache(2)事件驱动模型&#xff1a;Nginx(3)反向代理(4)负载均衡 三、workflow异步事件引擎 (异步回调模型)1.服务器底…

Qt找不到QSound头文件,头文件QSoundEffect

目录 Qt找不到QSound头文件 CMake qmke 可能版本不同更新&#xff0c; 找不到QSound头文件 Qt找不到QSound头文件 #include <QSound> CMake 可以看一下这篇来自网上的文章 CMake中添加Qt模块的合理方法 - wjbooks - 博客园 (cnblogs.com) qmke 打开.pro文件&am…

[linux#39][线程] 详解线程的概念

线程&#xff1a;是进程内的一个执行分支。线程的执行粒度比进程要细 什么是线程&#xff1f; • 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程 是“一个进程内部的控制序列” • 一切进程至少都有一个执行线程 • …

BF算法,KMP算法

前言&#xff1a;今天我们来学习两种算法&#xff0c;BF算法和KMP算法。相信会让许多小伙伴们打开新世界的大门。 1 BF算法 实践是检验真理的唯一标准。举一个例子说明BF算法。现在我们要在一个主串中找子串的位置。那我们该如何解决这个问题呢&#xff1f;最简单的办法自然是…

Repeat方法:取模运算教材与Unity控制台输出数值不同的原因

学习该知识点的参考教材&#xff1a;Unity API解析/陈宏泉编著.——北京&#xff1a;人民邮电出版社&#xff0c;2014.9 编辑脚本的环境&#xff1a;Visual Studio 2022 在学习该本教材的第五章Mathf类的内容&#xff0c;通过跟随教材上的代码了解不同UnityAPI的具体用法时&a…

【机器学习】线性回归与逻辑回归的极致解析:从数学理论到实战案例

文章目录 1. 引言Python 代码示例 2. 线性回归2.1 线性回归的基本概念线性回归的定义数学表达式及模型假设 2.2 线性回归的工作原理最小二乘法&#xff08;Ordinary Least Squares, OLS&#xff09;梯度下降法在线性回归中的应用多元线性回归与一元线性回归的区别与联系 2.3 线…

什么是AR、VR、MR、XR?

时代背景 近年来随着计算机图形学、显示技术等的发展&#xff0c;视觉虚拟化技术得到了广泛的发展&#xff0c;并且越来越普及化&#xff0c;慢慢的也走入人们的视野。目前市场上视觉虚拟化技术的主流分为这几种 VR、AR、MR、XR。这几项技术并不是最近才出现的&#xff0c;VR的…

机器学习笔记 第十二章计算学习理论

12.1 基础知识 计算学习理论就是关于机器学习的理论基础&#xff0c;其作用就是分析学习任务的困难实质&#xff0c;通过分析结果来知道算法设计&#xff0c;并为学习算法提供理论保证。 给定样例集&#xff0c;&#xff0c;假设为二分类问题&#xff0c;一般。假定中的所有样…

GoMail发送邮件的性能优化策略有哪些方法?

GoMail发送邮件如何配置服务器&#xff1f;GoMail发信功能如何&#xff1f; GoMail是一款广受欢迎的Go语言邮件发送库&#xff0c;具备高效、易用等优点&#xff0c;但在高并发场景下&#xff0c;GoMail发送邮件的性能优化显得尤为重要。AokSend将探讨几种有效的GoMail发送邮件…

PDF Shaper Ultimate v14.4 中文授权版

如今对PDF处理的软件很多都是只是单一的功能。PDF Shaper给你完全不同的体验&#xff0c;因为PDF Shaper是一款PDF工具集合的软件。有了PDF Shaper&#xff0c;你以后再也不用下载其他处理PDF的软件了。PDF Shaper的功能有&#xff1a;合并&#xff0c;分割&#xff0c;加密和解…

贪吃蛇(C语言详解)

贪吃蛇游戏运行画面-CSDN直播 目录 贪吃蛇游戏运行画面-CSDN直播 1. 实验目标 2. Win32 API介绍 2.1 Win32 API 2.2 控制台程序&#xff08;Console&#xff09; 2.3 控制台屏幕上的坐标COORD 2.4 GetStdHandle 2.5 GetConsoleCursorlnfo 2.5.1 CONSOLE_CURSOR_INFO …

ant design pro access.ts 是如何控制多角色的权限的

ant design pro 如何去保存颜色ant design pro v6 如何做好角色管理ant design 的 tree 如何作为角色中的权限选择之一ant design 的 tree 如何作为角色中的权限选择之二 看上面的图片&#xff0c;在前端中如何控制这些权限&#xff0c;比如控制按钮的显示&#xff0c;还有菜单…

【Linux操作系统】进程控制

目录 一、进程创建1.1 认识fork1.2 写时拷贝 二、进程终止2.1 进程退出2.2 函数退出2.3 exit 三、进程等待四、程序替换 一、进程创建 1.1 认识fork fork函数是系统调用接口&#xff0c;用来创建子进程的 根据进程的pid&#xff0c;可以看出父进程fork后分为父进程和子进程…

找到你的任务管理伙伴:待办事项软件终极指南

国内外主流的10款待办事项管理软件对比&#xff1a;PingCode、WorktileTodoist、TickTick、Teambition、 Microsoft To Do、. Asana、Tower、番茄ToDo、飞书。 在面对日益复杂的工作和个人任务时&#xff0c;找到一款能够有效帮助你管理日常待办事项的软件&#xff0c;变得越来…