Chinaunix首页 | 论坛 | 博客
  • 博客访问: 48130
  • 博文数量: 45
  • 博客积分: 1112
  • 博客等级: 少尉
  • 技术积分: 575
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-03 11:47
文章分类

全部博文(45)

文章存档

2013年(45)

我的朋友

分类: IT职场

2013-01-03 13:42:12

1,假设函数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
  2. else if n == 4*m + 1, then f(n) = 1
  3. else if n == 4*m + 2, then f(n) = n+1
  4. else n = 0
其中m为整数,公式的证明可以采用数学归纳法。
异或的的性质:
x^x = 0, 0^x=x, a^b^a=b
2, 利用异或的这些性质,我们可以在不需要任何额外空间的情况下交换两个变量的值:
     方法:利用异或交换整数a,b的值。简化代码为 : a ^= b ^= a ^= b; (&a != &b)
3,  1-1000放在含有1001个元素的数组中,只有唯一的一个元素值重复,其它均只出现一次。
    每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

  这题一个很简单的解法是将1001个数相加再减去1-1000的和,但是如果数据更大可能导致计算的和太大而溢出。 

  但是如果用异或运算则不会有这个问题。

  方法: 将1001个数进行异或,在与1-1000的异或进行异或
4, 有N个整数,除了其中的两个数只出现一次以外,其余的所有的数都正好出现两次,如何用最快的方法求    出只出现一次的两个数,要求空间复杂度是O(1).
  1. 三 解决方案
  2.     首先 回忆 异或操作,任意数字与自身相异或,结果都为0.
  3.    还有一个重要的性质,即任何元素与0相异或,结果都为元素自身。
  4.    
  5.    解决方案:
  6.   1 从数组的起始位置开始,对元素执行异或操作,则最后的结果,即为此只出现了一次的元素。
  7.  
  8.   2 题目中,数组中存在两个不同的元素,若是能仿造上述的解决方案,将两个元素分别放置在两个数组中,然后分别对每个数组进行异或操作,
  9.      则所求异或结果即为所求。
  10.   
  11.   3 首先对原数组进行全部元素的异或,得到一个必然不为0的结果,然后判断该结果的2进制数字中,为1的最低的一位。
  12.       然后根据此位是否为1 ,可以把原数组分为两组。则两个不同的元素,必然分别在这两个数组中。
  13.   4 然后对两个数组,进行异或操作,即可得到所求。

  14. 四 代码示例
  15. #include <iostream>
  16. #include <cstring>
  17. #include <cstdio>

  18. using namespace std;
  19. const int N = 10;

  20. int getSingle(int *a) { //获取全部元素的异或结果
  21.     if(!a) { //
  22.         return -1;
  23.     }
  24.     int sum = a[0];
  25.     for(int i = 1; i < N; i++) {
  26.         sum ^= a[i];
  27.     }
  28.     return sum;
  29. }
  30. void getTwo(int *a, int &one, int &two, int sum) {
  31.     unsigned int flag = 1;
  32.     while(1) {
  33.         if(flag&sum)
  34.             break;
  35.         flag = flag << 1;
  36.     }
  37.     one = 0;
  38.     two = 0;
  39.     for(int i = 0; i < N; i++) {
  40.         if(a[i]&flag) {
  41.             one ^= a[i];
  42.         }
  43.         else {
  44.             two ^= a[i];
  45.         }
  46.     }
  47.     cout << sum << ' ' << one << ' ' << two << endl;
  48. }
  49. int main() {
  50.     int a[N] = {3, 5, 8, 8, 5, 3, 1, 4, 4, 10};
  51.     int single = getSingle(a);
  52.     int one = 0;
  53.     int two = 0;
  54.     getTwo(a, one, two, single);
  55.     system("pause");
  56.     return 0;
  57. }

阅读(1393) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:学习C语言- 第一步关键字特点方法(1)

给主人留下些什么吧!~~