zoukankan      html  css  js  c++  java
  • XOR异或解惑

    https://leetcode.com/problems/single-number-ii/

    Given an array of integers, every element appears three times except for one. Find that single one.

    在网上看了解答,其中一种解法是用二进制模拟三进制,代码如下:

     1 int singleNumber(int A[], int n) {
     2     int ones = 0, twos = 0, xthrees = 0;
     3     for(int i = 0; i < n; ++i) {
     4         twos |= (ones & A[i]);
     5         ones ^= A[i];
     6         xthrees = ~(ones & twos);
     7         ones &= xthrees;
     8         twos &= xthrees;
     9     }
    10     return ones;
    11 }
     1 class Solution {
     2 public:
     3     int singleNumber(int A[], int n) {
     4         int one,two,three;
     5         one=two=three=0;
     6         for(int i=0;i<n;i++)
     7         {//一定是出现3次,2次,1次这样的顺序,如果反过来的话,先更新了one的话,会影响到two和three的
     8             three =  two & A[i];//已经出现了两次,还出现了一次
     9             two = two | one & A[i];//出现了1次又出现了1次,在加上以前已经出现了2次的,为新的出现了2次的
    10             one = one | A[i];//出现了1次
    11             //将出现3次的其出现1次2次全部抹去
    12             one = one & ~three;
    13             two = two & ~three;
    14         }
    15          return one;
    16     }
    17 };

    这个是用ones 和 twos 分别表示两个bit,要实现计算3的倍数,这俩bit的变化规律是 (注意实际运算中A[ i ]就相当于1)

    twos     ones
      0          0
      0          1
      1          0
      1          1
      0          0
    当ones和twos都达到1时,用xthrees把他们都重置为0,这就是xthrees开始那三行的作用
    那么前两行计数  他利用的规律是
    第一行 计算twos : 当ones是0时,twos不变,(利用了 x|0==x) 当ones是1,twos变为1 ( ones 是1 twos 一定是0 而 0|x==x)
    第二行 计算ones : 简单的xor,偶数次为0,奇数次为1

    顺便贴个讨论里那个更简洁的代码  原理一样的

    1 public int singleNumber(int[] A) {
    2         int zeros=0, ones=0;
    3         for (int i=0; i<A.length; i++){  // 00 -> 01 -> 10 -> 00
    4             zeros = (zeros^A[i]) & ~ones;  // if bit1 is 1 we should put bit0 as 0, otherwise just count
    5             ones = (ones^A[i]) & ~zeros;  // if bit0 is 1 we should put bit1 as 0, otherwise just count
    6         }
    7         return zeros|ones;
    8 }

    其实只要理解什么是XOR就好。

    A XOR B = (A+B)%进制。
    如果是10进制,7 XOR 8 = (7+8)%10 = 5
    一种思想就是把二进制XOR改成三进制XOR就好

    所谓single number,其实就是bit统计
    你可以按照 bit by bit 统计
    single number II,你可以把bit加到一起
    所有number第一bit的sum
    所有number第二bit的sum...
    然后sum%3 (bit by bit) 就是结果...

    single number问题最难的是k number问题
    Given an array of integers, every element appears X times except for k numbers (that only appear once). Find that k numbers.

    其实就是有点不能理解为什么A XOR B = (A+B)%进制?“A XOR B”就是一个确定的数,后面的“进制”是可变的,这两个东西怎么能相等?
    你下面说的这个方法我倒是能理解,当时提交的时候也是用这个方法过的,我只是看到另外那种解法对位运算这些东西有点看不懂所以贴出代码问问大家。

    7+8 = 15 是十进制+定义

    7+8 = F   是十六进制+定义

    A XOR B = (A+B)%进制 这就是XOR的一种定义,结果就是和进制本身有关重复相加到进位,然后不进位而归零,叫做XOR,如果进位,就叫做加法

    // K number
    class Solution {
    public:
        int singleNumber(vector<int>& nums) {
            int len = sizeof(int) * 8;
            int res = 0;
            for (int i = 0; i < len; i++) {
                int sum = 0;
                for (int j = 0; j < nums.size(); j++) {
                    sum += (nums[j] >> i) & 0x01;
                }
                res += (sum % 3) << i;
            }
            return res;
        }
    };

    时间:O(32*N),这是一个通用的解法,如果把出现3次改为 k 次,那么只需模k就行了。

    http://www.1point3acres.com/bbs/thread-111563-1-1.html

  • 相关阅读:
    Firemonkey 控件设定字型属性及颜色
    ListView 使用 LiveBindings 显示超过 200 条记录
    Firemonkey ListView 获取项目右方「>」(Accessory) 事件
    XE7 Update 1 选 iOS 8.1 SDK 发布 iPhone 3GS 实机测试
    Firemonkey Bitmap 设定像素颜色 Pixel
    Firemonkey 移动平台 Form 显示使用 ShowModal 范例
    XE7 提交 App(iOS 8)提示「does not contain the correct beta entitlement」问题修复
    XE7 Android 中使用 MessageDlg 范例
    导出 XE6 预设 Android Style (*.style) 档案
    修正 Memo 設定為 ReadOnly 後, 無法有複製的功能
  • 原文地址:https://www.cnblogs.com/daijkstra/p/4810247.html
Copyright © 2011-2022 走看看