位运算小合集(异或,按位与)

一、

       整型数组内除了一个数字x出现过一次,其他数字都出现过两次;

       解法很简单,令一个数初始化为0,然后异或整个数组就是最后的答案;

       关于整数a,

                         (1)a^a=0

                         (2)a^0=a

                         (2)a^b^c=a^(b^c)=(a^c)^b

二、

      整型数组内x,y各出现过一次,其他数字出现过两次,输出x,y的值;

      首先令sum=0,去异或整个数组,此时得到的结果就是x^y,因为x!=y,所以此时sum化为二进制后一定有位上为一的存在;

      找到这个位,就获得了将数组分为两部分的条件,因为这是x^y之后的结果,所以x和y在二进制中该位上一定不同;

      然后令x=y=0,去异或数组进行for循环,如果相应位上结果为1,则用x去异或,其他用y异或;

      参考代码:

       

#include<bits/stdc++.h>
using namespace std;
int main()
{
   int n,sum=0,s,a[1000],x=0,y=0;
   cin>>n;
   for(int i=1;i<=n;i++)
   {
       cin>>a[i];
       sum^=a[i];
   }
   int i=0;
   while(1)
   {
       if(sum&(1<<i)==1)
       {
           break;
       }
       i++;
   }
   for(int j=1;j<=n;j++)
   {
       if(a[j]&(1<<i)==1)
       {
           x^=a[j];
       }
       else
       {
           y^=a[j];
       }
   }
   cout<<x<<" "<<y<<endl;
}

三、

          数组中除了x出现过一次外,其他数字都出现过三次;

          将所有数字对应二进制位上为1的加起来,对3求余,不能整除的一定是x中出现过的位,记下来最后返回即可;

     

int Find(int a[], int n)  
{  
  int bits[32];  
  int i, j;  
  // 将所有数字中的二进制位为1的累加  
  memset(bits, 0, 32 * sizeof(int));  
  for (i = 0; i < n; i++)  
    for (j = 0; j < 32; j++)  
      bits[j] += ((a[i] >> j) & 1);  
  //如果不能整除3,则相应为则是所求数字存在的
  int result = 0;  
  for (j = 0; j < 32; j++)  
    if (bits[j] % 3 != 0)  
      result += (1 << j);  
  return result;  
}  

猜你喜欢

转载自blog.csdn.net/WN_795/article/details/81564802