位运算可以大大减小算法空间复杂度,提高效率,很巧妙!

先说一下位运算的简单用法

1. 按位与 &

用途:清零,取一个数中的某些指定位,保留一个数中的某些指定位

2. 按位或 |

用途:将一个数的某些位指定为1

3. 按位异或 ^

用途:交换两个数

a=a^b; b=a^b; a=a^b

让我们看看这三条语句执行后的结果:

第一条a=a^b,所以第二条b=a^b=(a^b)^b=a^(b^b)=a^0=a,现在b的值是a

第三条a=a^b=(a^b)^a=b^(a^a)=b^0=b,现在a的值是b啦!完成互换!

4. 取反 ~

5. 左移 << , 右移 >>

位运算最大的优点就是操作简单,效率高。可以看如下例子:

1. 假设一个变量有如下属性{输入,输出,类型,长度(如果是数组的话;如果不是数组那么长度为0)},试问你如何表示这个变量呢?

用一个结构体来表示这些属性?甚至用一个类?。。。嘿嘿,事实上只用一个int型就OK了。一个int型有32位,足够了,我们可以任意设置标志位的位置。比如第32位表示输出,第31位表示输入,第17-24位表示类型,第1-16位表示长度。好啦,如果一个变量是输入(则32位是1),不是输出(则31位是0),类型是char(假设char对应1,那么17-24位是00000001),长度是5,下面的int type可以表示全部信息:

int type=(1<<31)|(1<<16) |5

以后可以通过按位与来取得任何信息,比如要取得长度,可以type & 0x0000FFFF

2. 棋盘的表示:

选择什么样的数据结构可以表示一个棋盘呢?二维数组肯定是大多数人冒出的第一想法,不过二维数组操作起来不并像想象那么简单。如果棋盘是8*8的,实际上我们可以用一个64位长度的变量来表示棋盘。每一位对应棋盘的每一格。对于传统的只有黑白子的游戏,可以使用两个变量:第一个64位变量记录黑子的棋盘情况(如果棋盘的[i][j]位置有黑子,则第(i-1)*8+j位是1,否则是0),同样,第二个64位变量记录白子的棋盘情况。这样,判断棋子、吃子、翻转子等操作就可以用与、或、异或等位运算很方便高效地实现了。有些棋类游戏存在基本的“棋局”模式,而这个模式则可以用另一个变量记录。这个变量作为一个模版,可以与原棋盘变量进行位运算来判断原棋盘是否出现了这样一个特定的棋局模式。而如果用数组来表示棋盘,这些操作则会复杂许多。

而对于象棋这样的棋类游戏,棋子的种类并不是只有一黑一白的,应该要维持多个棋盘变量,具体可以参考以下链接:

http://www.elephantbase.net/computer/struct_bitboard.htm

1. 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。

  例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。

  按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为0000000011111111)。

  应用:

  a. 清零特定位 (mask中特定位置0,其它位为1,s=s&mask)
  b. 取某数中指定位 (mask中特定位置1,其它位为0,s=s&mask)   2. 按位或运算 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。   例如:9|5可写算式如下:   00001001|00000101
  00001101 (十进制为13)可见9|5=13   应用:   常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)   3. 按位异或运算 按位异或运算符“^”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。参与运算数仍以补码出现,例如9^5可写成算式如下:   00001001^00000101 00001100 (十进制为12)   应用:   a. 使特定位的值取反 (mask中特定位置1,其它位为0 s=s^mask)
  b. 不引入第三变量,交换两个变量的值 (设 a=a1,b=b1)
  目 标 操 作 操作后状态
  a=a1^b1 a=a^b a=a1^b1,b=b1
  b=a1^b1^b1 b=a^b a=a1^b1,b=a1
  a=b1^a1^a1 a=a^b a=b1,b=a1   4. 求反运算   求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110   5. 左移运算   左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数, 高位丢弃,低位补0。 其值相当于乘2。例如: a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00110000(十进制48)。   6. 右移运算   右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。其值相当于除2。   例如:设 a=15,a>>2 表示把000001111右移为00000011(十进制3)。对于左边移出的空位,如果是正数则空位补0,若为负数,可能补0或补1,这取决于所用的计算机系统。移入0的叫逻辑右移,移入1的叫算术右移,Turbo C采用逻辑右移。

leetcode-位运算的更多相关文章

  1. leetcode - 位运算题目汇总(下)

    接上文leetcode - 位运算题目汇总(上),继续来切leetcode中Bit Manipulation下的题目. Bitwise AND of Numbers Range 给出一个范围,[m, ...

  2. leetcode - 位运算题目汇总(上)

    最近在看位运算的知识,十分感叹于位运算的博大精深,正好leetcode有 Bit Manipulation 的专题,正好拿来练练手. Subsets 给出一个由不同的数字组成的数组,枚举它的子数组(子 ...

  3. 78 leetCode 位运算解法

    按照自己的理解题目,数组内所有的组合:假如[1,2,3,4]看成1111到0000里面的排列组合,取位运算. vector<vector > subsets(vector&nums ...

  4. leetcode.位运算.136只出现一次的元素-Java

    1. 具体题目 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明:你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1 ...

  5. BitMap - leetcode [位运算]

    136. Single Number 因为A XOR A = 0,且XOR运算是可交换的,于是,对于实例{2,1,4,5,2,4,1}就会有这样的结果: (2^1^4^5^2^4^1) => ( ...

  6. leetcode 位运算异或

    1. 只出现一次的数字(136) 异或的性质总结: 相异为1,相同为0: a ^ a = 0; 0 ^ a = a; 如果 a ^ b = c 成立,那么a ^ c = b 与 b ^ c = a 均 ...

  7. JavaScript 位运算总结&拾遗

    最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识. 把一个数变为大于等于该数的最小的2的幂 一个 ...

  8. 位运算总结&拾遗

    JavaScript 位运算总结&拾遗 最近补充了一些位运算的知识,深感位运算的博大精深,此文作为这个系列的总结篇,在此回顾下所学的位运算知识和应用,同时也补充下前文中没有提到的一些位运算知识 ...

  9. LeetCode解题中位运算的运用

    位运算是我最近才开始重视的东西,因为在LeetCode上面刷题的时候发现很多题目使用位运算会快很多.位运算的使用包含着许多技巧(详细可以参考http://blog.csdn.net/zmazon/ar ...

  10. LeetCode编程训练 - 位运算(Bit Manipulation)

    位运算基础 说到与(&).或(|).非(~).异或(^).位移等位运算,就得说到位运算的各种奇淫巧技,下面分运算符说明. 1. 与(&) 计算式 a&b,a.b各位中同为 1 ...

随机推荐

  1. scala模式匹配与样例类

    样本类:添加了case的类便是样本类.这种修饰符可以让Scala编译器自动为这个类添加一些语法上的便捷设定.如下: 1.添加与类名一致的工厂方法.也就是说,可以写成Var("x") ...

  2. PAT (Advanced Level) 1102. Invert a Binary Tree (25)

    简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...

  3. FragmentTabHost使用注意

    FragmentTabHost使用时每次切换回Fragment时,都会再走一遍onCreateView,解决办法是缓存View,具体如下 private View rootView;//缓存Fragm ...

  4. 转:Eclipse Debug 界面应用详解——Eclipse Debug不为人知的秘密

    今天浏览csdn,发现一文详细的描述了Eclipse Debug中的各个知识点,非常详尽!特此记录. Eclipse Debug不为人知的秘密 http://blog.csdn.net/mgoann/ ...

  5. hdu_5719_Arrange(脑洞题)

    题目连接:hdu_5719_Arrange 题意: 给你1-n这 n个数,设一个排列的第i个数为Ai, Bi为A1到Ai的最小值,Ci为C1到Ci的最大值,问你有多少种排列方式,然后输出取模后的答案 ...

  6. HBase伪分布安装

    1把hbase-0.94.2-security.tar.gz复制到/usr/local 2 解压缩.重命名.设置环境变量 cd /usr/local tar -zxvf hbase--security ...

  7. 干货分享:MySQL之化险为夷的【钻石】抢购风暴【转载】

    转自: 干货分享:MySQL之化险为夷的[钻石]抢购风暴 - Vanos_韩尛哲 - 博客园http://www.cnblogs.com/Vanos-lcp/p/5642097.html 抢购钻石不稀 ...

  8. (转)Permission denied: win7下面eclipse上传本地文件到DFS && 运行M/R程序时出现的同样的错误解决方法

    原文地址: http://mntms.iteye.com/blog/2095651 hadoopeclipse远程控制权限  情景一: 当在win7下面的eclipse装好插件,首次运行M/R程序的时 ...

  9. DWR Annotations

    DWR   Annotations DWR 标注是用来代替 dwr.xml 或者与其一同工作的. 1.初始配置 <servlet> <description>DWR contr ...

  10. HDU 5547 暴力

    Sudoku Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Subm ...