前言
本文将先介绍“异或运算”的相关知识点,然后再讲解有关“异或运算”的入门经典的“单身狗”问题(初阶版)
一、什么是异或?异或运算 的神奇之处!
1.异或的定义与性质(运算法则)
定义
首先,异或的定义可以直接简单粗暴的说就是:
对应数值二进制形式的对应位无进位相加
(异或符号“^”——你电脑的“数字6”键(按“Shift+6”))
那啥叫对应二进制位无进位相加呢?
举个例子:
5+7等于12,那5^7等于多少呢?大家可以先把5和7的二进制写出来,试着运用“无进位相加”的异或运算规则感受一下,如果没绕过来的话,直接看我得计算过程:

性质(运算法则)
而至于性质,我认为你只要理解了异或的“无进位相加”,然后再看百度百科上总结得全面的”异或规律“,你就能记得很深刻!性质(运算法则)如下:

2."单身狗"问题引入
那知识你不用它,那肯定是不容易记住的;你得尝试去用它,才会容易记得住!那接下来,我们就来尝试用”异或运算“的这个知识点来解决这个“屏幕前的各位 单身狗”问题吧!
二、单身狗问题
1.题目内容
题目要求如下:

在看题解之前,请确保自己经历过“思考”的这个过程!就像数学题,自己先尝试解法再看答案,比直接看答案记忆更深刻哦!
2.常规思路
如果大家没有很熟悉“异或运算”的性质,那首先想到的可能就是:设置一个“标记变量”,然后直接循环遍历数组中的每个元素,将每个元素与数组中其它的元素去相互比较是否相等; 若相等,则修改“标记变量”的初始值 ,最后若一轮循环下来,“标记变量”的值还是为初始值 0,则说明当前这个元素就是"单身狗"。
直接上Code:
void Single_Dog(int p[], int len)
{
int temp = 0; //临时变量temp:用来存当前遍历的数组元素
for (int i = 0; i < len; i++) //因为要考虑最坏情况:“单身狗”可能为数组的最后一个元素,所以要遍历整个数组中的元素;(后续若提前找到“单身狗”了,直接break跳出循环即可)
{
int flag = 0; //“标记变量”flag,初始值为0
temp = p[i];
for (int j = i+1; j < len; j++) //将当前数组元素与数组中其它元素进行互相比较是否相等
{
if (temp == p[j])
{
flag = 1; //若相等,则更改“标记变量”flag的初始值0(每遍历一个新的数组元素,flag都会被初始化成0,所以相应的,初始值0 -> 1)
break; //此时,走到这一步,说明当前遍历的数组元素不是“单身狗”,所以直接break,提前跳出循环
}
}
if (!flag) //flag还是初始值 0 ,说明当前遍历到的数组元素在数组中没有别的元素与它“相等”,即它为“单身狗”
{
printf("%d", p[i]); //输出这个“单身狗”元素
break;
}
}
//函数结束
3.“异或和”解法

我们再来看一下题目中给到我们的“关键题眼”:
成对且只有一个数字是单独出现的
看到这里,不知道大家有没有联想到我前面给出的根据“异或运算”而总结出的异或性质:归零律,即2个相同的数字经过“异或运算”得出来的结果是“0”。
那知道这个了,大家在思考一下,假如我现在将所有的数组元素都经过“异或运算”异或起来,即“累异或”(异或是种“运算”,那我在做把所有的元素都“加”到一起的时候,这个操作叫“累加”;那现在把所有的元素都“异或”到一起的时候,是不是可以叫“累异或”),那得到的最后的结果是不是就是那个“单身狗”元素了。
直接上Code:
#include <stdio.h>
int find_single_dog(int arr[], int sz)
{
int ret = 0;
int i = 0;
for (i = 0; i < sz; i++)
{
ret ^= arr[i]; //依次将所有数组元素“累异或”起来
}
return ret; //此时返回的 "ret"里存放的数据就是那个单独存在的元素,即题目要的“单身狗”
}
int main()
{
int arr[] = { 1,2,3,4,5,1,2,3,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
int dog = find_single_dog(arr, sz);
printf("%d\n", dog);
return 0;
}
总结
以上就是本文讲述的有关“异或运算”的知识点内容,同时最后介绍和讲解了有关“异或运算”的经典入门“单身狗”问题(初阶版)。之后我还会再更新“单身狗”问题(进阶版)。
若读者们对本文涉及到的问题还有“异或 疑惑”,欢迎评论区留言告诉我,或者私信问我。
118

被折叠的 条评论
为什么被折叠?



