关于异或

笔试的时候碰到一些跟异或有关的题目,在这里总结一下。

当初学到异或的时候就只是记住了一个口诀,“相同为0,相异为1”,然而并没有了解它的用途所在,所以在碰到那些题目也没有想到所考的知识点其实是异或。

首先来了解异或的一些基本性质:

1. 交换律

2. 结合律

3. x^x = 0; x^0 = x;

因此异或可以用于:

1. 交换两个整数的值(无需用第三个参数)

    1)交换两个整数a, b的值还可以用到其他的方法,如加减法,即

    a = a + b;

    b = a - b;

    a = a - b;

    2)但是当a, b数值太大的时候考虑到会有溢出的危险,因此异或的方法更好。

    a = a^b;

    b = a^b;  // new_b = (a^b)^b = a^b^b = a^0 = a;

    a = a^b;  // new_a = (a^b)^a = a^b^a = a^a^b = 0^b = b;

2. 1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

1)同样也可以用加减法,将该数组中的1001个数相加,再减去1-1000的和,遇到更大的数据同样可能会有溢出的危险

2)异或的方法

    将该数组的每个元素相异或,在分别于1-1000异或,即:

    x = (1001个数的异或)^(1^2^3^4^...^999^1000)

    计算(1^2^3^4^...^999^1000)有这样一个结论,是我从一个博客上看到的:

    假设函数f(n)是自然数1,2,3,...,n的所有数的异或,即f(n)=1^2^3^...^n, 那么,任意的n(n为自然数),我们能够很快的计算出f(n)的值  

  1.      if n == 4*m, then f(n) = n

         else if n == 4*m + 1, then f(n) = 1

         else if n == 4*m + 2, then f(n) = n+1

         else n = 0
  1.      其中m是整数;
3. 有2n+1个数,其中有n个是成对出现的,找出只出现一次的数     异或!异或!异或!重要的事情说三遍!数组内的每个元素相异或,O(n)时间,O(1)空间:
  1.     假设arr = { 1, 2, 3, 4, 5, 1, 2 , 3, 4 }
  1.     x = 1^2^3^4^5^1^2^3^4 = (1^1)^(2^2)^(3^3)^(4^4)^5 = 0^0^0^0^5 = 5;
  1.    当然啦,代码是酱的...
#include 
using namespace std;
int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 1, 2, 3, 4 };
	int x = 0;
	cout << sizeof(arr) << endl;
	for (int i = 0; i < (sizeof(arr)/sizeof(int)); ++i)
	{
		x ^= arr[i];
	}
	cout << x << endl;
	return 0;
}





你可能感兴趣的:(笔试面试)