位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。

位运算的用处很多,也很强大。

首先再学习位运算之前,我们先复习以下,编码知识

在计算机中,正数是直接用原码表示的,如5,在计算机中就表示为:0000 0101。

负数用补码表示,如-5,在计算机中表示为1111 1011。

原码  反码 补码问题

原码:将一个整数,转换成二进制,就是其原码。

如:3的二进制是 0000 0011 原码就是0000 0011  -3的原码是 1000 0011

反码:正数的反码就是其原码;负数的反码是将原码中,除符号位以外,每一位取反。

如 3的反码是 0000 0011   -3的反码是 1111 1100

补码:正数的补码就是其原码;负数的反码+1就是补码。

如 3的补码是 0000 0011   -3的补码是1111 1101

位运算:

& 按位与操作

相同位的两个数字都为1,则为1;若有一个不为1,则为0。

3&5          3:       0000 0011

5:       0000 0101

&————————

3&5         0000 0001

|  按位或操作

相同位只要一个为1即为1。

3|5       3:       0000 0011

5:       0000 0101

|————————

3|5:        0000 0111

^按位异或操作

规则:两个数对应位相同 运算结果为0  对应位不同 运算结果为1

3^5    3:       0000 0011

5:       0000 0101

^————————

3^5         0000 0110

性质:异或运算满足结合律和交换律

满足消去律  a^b=b^c  则a=c

a^a=0   (a^b)^b=0

所以 交换两个数的方法可以这么写:

void swap(int a,int b)
{a=a+b;b=a-b;a=a-b;
}
void swap(int a,int b)
{a=a^b;b=a^b;a=a^b;
}

~按位取反

~是一个单目运算符 作用是对二进制每一位数取反

3  0000 0011

~3  1111 1100

*例如 -1在计算机里的补码是 1111 1111

所以 ~(-1)=0000 0000 =0

所以ACM中经常看到 while(~scanf("%d",&a))   代表 scanf返回-1(即EOF)时结束

<<左移运算符              >>右移运算符

<<左移  按照指定的位数将一个数的二进制数值向左移位   左移后 低位补0 移除的高位舍弃

>>右移  按照指定的位数将一个数的二进制数值向右移位   移除的低位舍弃  如果是无符号数则高位补0  若有符号 则高位补符号或者补0(不同处理器不一样)

如  a=-8  内存中补码为1111 1000

则a>>2=-2     右移两位后为  1111 1110   为-2

状态压缩

这是位运算的一个重要应用

比如 一个迷宫  1代表墙  0代表可以走   通常我们用二维数组存迷宫 做BFS或DFS

那么  迷宫不大的时候 我们可以用二进制数来表示这个迷宫

我们可以把n*m的迷宫  每一行表示为一个m位的二进制数  那么n个整数 就可以表示这个迷宫了

同样的  如果n*m不大的话   我们也可以把整个迷宫 表示为一个n*m位的二进制数

而迷宫的各种操作  我们可以借助位运算来完成  如下表

(切记  位运算的优先级很低! 使用的时候 一定记得带上括号)

去掉最后一位   (101101->10110) x >> 1
在最后加一个0 (101101->1011010) x << 1
在最后加一个1 (101101->1011011) (x << 1)+1
把最后一位变成1 (101100->101101) x | 1
把最后一位变成0 (101101->101100) (x | 1)-1
最后一位取反 (101101->101100) x ^ 1
把右数第k位变成1 (101001->101101,k=3) x | (1 << (k-1))
把右数第k位变成0 (101101->101001,k=3) x & ~(1 << (k-1))
右数第k位取反  (101001->101101,k=3) x ^ (1 << (k-1))
取末k位 (1101101->1101,k=5) x & (1 << (k-1))
取右数第k位  (1101101->1,k=4)  (x >> (k-1)) & 1
把末k位变成1 (101001->101111,k=4)  x ^ (1 << (k-1))
末k位取反 (101001->100110,k=4)  x^ (1 << (k-1))
把右边连续的1变成0 (100101111->100100000) x & (x+1)
把右起第一个0变成1 (100101111->100111111) x | (x+1)
把右边连续的0变成1 (11011000->11011111) x | (x-1)
取右边连续的1 (100101111->1111)  (x ^ (x+1)) >> 1

位运算初步入门状态压缩操作相关推荐

  1. 【题解】《算法零基础100讲》(第44讲) 位运算 (位或) 入门

    文章目录 一. 概念定义 1.1 位或定义 1.2 位与定义 二. 推荐专栏 三. 相关练习 3.1 根据数字二进制下 1 的数目排序 3.2 二进制表示中质数个计算置位 3.3 2 的幂 一. 概念 ...

  2. 黑白棋游戏 (BFS + 位运算初步运用)

    题目描述   黑白棋游戏的棋盘由4×4方格阵列构成.棋盘的每一方格中放有1枚棋 子,共有8枚白棋子和8枚黑棋子.这16枚棋子的每一种放置方案都构成一个游戏状态.在棋盘上拥有1条公共边的2个方格称为相邻 ...

  3. 【基本算法】 位运算:二进制状态压缩

    二进制状态压缩 二进制状态压缩,是指将一个n位的 bool 数组用 n 位的二进制数表示的方法. OP 运算 取出 n 在二进制表示下的第k位 (n >> k) & 1 取出 n ...

  4. java 位运算 多个状态_位运算表示对象所处状态

    通过一个integer类型属性来表示对象所处的状态: CASE: Invitor:邀请者对象模型 Integer Invitor.joinstatus:邀请者所处参加状态 当前存在状态声明:是否被邀请 ...

  5. 《算法零基础100讲》(第42讲) 位运算 (位与) 入门

    文章目录 零.写在前面 一.概念定义 1.位与的定义 2.位与运算符的简单应用 1)奇偶性判定 2)取末五位 3)消除末尾五位 4)2的幂判定 二.题目描述 三.算法详解 四.源码剖析 五.推荐专栏 ...

  6. C语言每日一练 —— 第20天:位运算

    文章目录 一.前言 二.再谈二进制 1.二进制数值表示 2.二进制加法 3.二进制减法 三.位运算简介 1.位与的定义 2.位与运算符的简单应用 1)奇偶性判定 2)取末五位 3)消除末尾五位 4)2 ...

  7. python位运算和float浮点型底层存储原理

    一 前言 位运算,一个极容易被低端码农忽视的地带,因为它略微需要用一丢丢智商,真的只有那么一丢丢,但高手与low手的差距往往就是长这么一丢丢,能达到的深度就截然不同了 二 真值.机器数(原码.反码.补 ...

  8. c++ 输出二进制_【位运算与状态压缩】二进制的魅力

    [引言] 今天讲讲位运算与状态压缩.         位运算涉及系统底层的运算,骚操作很多:状态压缩则是编程中空间优化的有效手段,应该说两者本身其实并没有太直接的联系,但是在实际使用时会有一定的结合, ...

  9. 洛谷P1562 还是N皇后(DFS+状态压缩+位运算)

    八皇后问题的介绍在此不再赘述,只贴一下经典八皇后问题的实现代码(参考刘汝佳 <算法竞赛入门经典>) void search(int i) {if(i>n){ans++;return; ...

  10. hdu3006 状态压缩+位运算+hash(小想法题)

    题意:        给了n个集合,问你这n个集合可以组合出多少种集合,可以自己,也可以两个,也可以三个....也可以n个集合组在一起. 思路:       是个小想法题目,要用到二进制压缩,位运算, ...

最新文章

  1. python守护进程进程池_Python进程池非守护进程?
  2. AutoScaling 弹性伸缩附加与分离RDS实例
  3. 详细理解java Hibernate 或 JPA的级联操作
  4. python windows窗口开发_Windows 平台做 Python 开发的最佳组合
  5. RTree算法及介绍
  6. 动态规划入门(一)——数字三角形
  7. c++ windows下declspec
  8. java jodd_Jodd :一款优雅的 Java 工具集
  9. achartengine画出动态折线图
  10. 使用终端shell命令批量改动一个文件下的全部文件的读写权限
  11. python使用sax实现xml解析
  12. 渗透杂记-2013-07-13 关于SMB版本的扫描
  13. C#后台调用跨域MVC服务,带Cookie验证
  14. DHT 爬虫的学习记录
  15. 在校大学生如何规划自己的程序员之路
  16. 当A题成为一种习惯--POJ AC100题纪念贴
  17. 刀塔霸业怎么在电脑上玩 刀塔霸业电脑版玩法教程
  18. java中直线距离的计算_java计算两点间的距离方法总结
  19. XXL之整合SpringBoot
  20. 关于logcat的使用

热门文章

  1. 泡水十几秒仍能工作 小米手机2也能防水了
  2. 玩转DataGridView之实现两个GRID间行的拖拽
  3. redis通过lua脚本实现分布式锁
  4. 分布式SQL引擎是如何炼成的 —— 运行时探秘(上)
  5. Activity的生命周期方面复习笔记
  6. Spring Cloud 关于 hystrix 的异常 fallback method wasn't found
  7. oneproxy出现2103错误代码解决方案
  8. mongoDB之监控工具mongotop
  9. 寻找二叉树最小叶子节点值
  10. Android 存储学习之保存系统短信到SD卡