ps:利用异或运算会让效率变得更高
耐心看 最通俗易懂,简单方法,全程注释。
异或运算:符号表示^
大白话:在二进制中位数对齐相同的为0,不同的为1
比如: 111^111 = 000 111^000 = 111; (任何一个数和0异或都是本身 好像1乘任何数=任何数)
记忆方法:如果相同就说明一模一样,所以二者差为0,否则就不一样二者差为非0也就是1;
立题:求一个数组,大小为11,里面有1-10之间的数,其中有重复的数字在里面找到这个数并且输出。
方法一:不借助任何存储空间,数组,集合都不用,只有……异或
#include<bits/stdc++.h>
using namespace std;
int main()
{
int arr[11];
for(int i = 0 ; i < 10 ; i++)
{
arr[i]=i+1;
} //该循环是为了生成1-10的数字放到数组前10个位置
srand(time(NULL)); //置随机数种子 为了取到不重复的数
arr[10] = rand()%10+1; //在数组最后一位 取随机数 通过算法找到该数
int temp = 0; //异或的性质 任何数 异或0 为本身
for(int i = 1 ; i<11;i++)
{
temp = temp^i; // 0异或(1-10)
}
for(int i = 0 ; i<11;i++)
{
temp = temp^arr[i]; //接着遍历异或数组中的数字
cout<<arr[i]<<" "; //输出数组中的每一个元素
}
cout<<endl<<temp;//ans 找到了重复的数字
return 0;
}
仔细读代码会发现 其实 1-10 我们异或了 俩次也就是说 相同的数字都俩俩异或为0 剩下最后一个数和 0 异或就为那个数。
方法二:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int arr[11],dic[11]={0};
for(int i = 0 ; i < 10 ; i++)
{
arr[i]=i+1;
}
srand(time(NULL));
arr[10] = rand()%10+1;
//以上和法一一样
for(int i = 0 ; i < 11 ; i++)
{
cout<<arr[i]<<" ";
dic[arr[i]] ++;
} //输出 数组中的值 然后利用 数组空间记录数字出现的值 让他++ 重复的值将会+到2 利用这个即可判断
for(int i = 0 ; i < 11 ; i++)
{
if(dic[arr[i]] !=1) //等价于 dic[arr[i]] ==2
{
cout<<arr[i];
break;
}
}
return 0;
}