acm算法模板(3)
位 运 算
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。运位算包括位逻辑运算和移位运算,位逻辑运算能够方便地设置或屏蔽内存中某个字节的一位或几位,也可以对两个数按位相加等;移位运算可以对内存中某个二进制数左移或右移几位等。
计算机内部是以补码形式存放数值的。C语言提供了六种位运算
位运算符及含义
位 运 算 符 |
含 义 |
举 例 |
&(and) |
按位与 |
a&b |
|(or) |
按位或 |
a|b |
^(xor) |
按位异或 |
a^b |
~(not) |
按位取反 |
~a |
<< (shl) |
左移 |
a<<1 |
>> (shr) |
右移 |
b>>2 |
位逻辑运算规则
a |
b |
a&b |
a|b |
a^b |
~a |
~b |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
假设a,b为整型的数据,并且设a=15(等于二进制数00000000 00001111),b=80(等于二进制数 00000000 01010000)
a的补码:00000000 00001111
b的补码:00000000 01010000
————————
a&b: 00000000 00000000 a&b=0x0
a|b : 00000000 01011111 a|b=0x5f
a^b : 00000000 01011111 a^b=0x5f
~a : 11111111 11110000 ~a=0xfff0
位运算应用口诀
清零取反要用与,某位置一可用或
若要取反和交换,轻轻松松用异或
1.“按位与”运算符&
运算规则:参加运算的两个运算量,如果两个数相应位的值都是1,则该位的结果值为1,否则为0。即:0 & 0 =0;0 & 1 =0;1 & 0 =0;1 & 1 =1。
(1)将某些二进制位屏蔽掉(保留一个数据中的某些位)。
如果要使整数k的低四位置零,保留其它位。用位与运算即可,将的高字节与0相与,低字节与1相与;
代码如下:unsigned int_set(unsigned int k)
{k=k&0x1110;
Return(k);}
例】00101010 01010010&11111111 11110000=00101010 01010010。
结论:任何二进制位与0能实现置0;与1保持原值不变
(2)判断一个数据的某一位是否为1。
如判断一个整数a(2个字节)的最高位是否为1,可以设一个与a同类型的测试变量test,test的最高位为1,其余位均为0,即int test=0x8000。
【例】 0100010011111110&1000000000000000=0 说明最高位为0;
1100010011111110&1000000000000000=1000000000000000 说明最高位为1;
例如一个数 and 1的结果就是取二进制的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数.
2.“按位或”运算符|
常用来将源操作数某些位置1,其它位不变。 (mask中特定位置1,其它位为0 s=s|mask)
运算规则:参加运算的两个运算量,如果两个数相应位的值都是0,。即:0 | 0 =0;0 | 1 =1;1 | 0 =1;1 | 1 =1
把一个数据的某些位置为1。
如果把a的第10位置为1,而且不要破坏其它位,可以对a和b进行“按位或”运算,其中b的第10位置为1,其它位置为0,即int b=0x400。
【例】00100000 01010010|00000010 00000000=00100010 01010010。
3.“按位异或”运算符^
运算规则:参加运算的两个运算量,如果两个数的相应位的值不同,则该位的结果值为1,否则为0。即:0 ^ 0 =0;0 ^ 1 =1;1 ^ 0 =1;1 ^ 1 =0
应用举例:
(1)把一个数据的某些位翻转,即1变为0,0变为1。
如要把a的奇数位翻转,可以对a和b进行“按位异或”运算,其中b的奇数位置为1,偶数位置为0,即int b=0xaaaa。
【例】a的补码:00000000 01010010
b的补码: 01010101 01010101
^ -------------------
结果的补码: 01010101 00000111
(2)交换两个值,不用临时变量。
【例】a=3,b=4。想将a和b的值互换,可以用以下三条赋值语句实现:
a=a^b;即:a=3^4=7(0011^0100=0111)
b=b^a;即:b=4^7=3(0100^0111=0011)
a=a^b;即:a=7^3=4(0111^0011=0100)
不用temp交换两个整数
void swap(int x , int y)
{
x ^= y;
y ^= x;
x ^= y;
}
编写对字符串进行密钥匙异或加解密程序
有了加密程序(a^b),相应的就应该有解密程序。解密程序是加密程序的逆过程,这里的加密和解密程序是完全相同的,原因是(a^b)^b=a。大家自己分析,并完善该实训。 }
4.“按位取反”运算符~
移位运算符:
左移、右移运算实现将一个数的各个二进制位向左向右移若干位。
1.左移运算符<<
运算规则:对运算符<<左边的运算量的每一位全部左移右边运算量表示的位数,右边空出的位补0。
【例】a<<2表示将a的各位依次向左移2位,a的最高2位移出去舍弃,空出的低2位以0填补。
例:char a=0x21;
则a<<2的过程 0010 0001〈〈2 = 1000 0100;即 a<<2的值为0x84。
左移1位相当于该数乘以2,左移n位相当于该数乘以2n。
乘法运算转化成位运算 (在不产生溢出的情况下)
a * (2^n) 等价于 a<< n
2. 右移运算符>>
运算规则:对运算符>>左边的运算量的每一位全部右移右边运算量表示的位数,右边低位被移出去舍弃掉,空出的高位补0还是补1,分两种情况:
(1)对无符号数进行右移时,空出的高位补0。这种右移称为逻辑右移。
(2)对带符号数进行右移时,空出的高位全部以符号位填补。即正数补0,负数补1。这种右移称为算术右移。
右移1位相当于除以2,同样,右移n位相当于除以2n。
除法运算转化成位运算 (在不产生溢出的情况下)
a / (2^n) 等价于 a>> n
取模运算转化成位运算 (在不产生溢出的情况下)
a % (2^n) 等价于 a & (2^n - 1)
循环移位的实现。
如将一个无符号整数x的各位进行循环左移4位的运算,即把移出的高位填补在空出的低位处。
可以用以下步骤实现:
(1)将x左移4位,空出的低4位补0,可通过表达式x<<4实现。
(2)将x的左端高4位右移到右端低4位,可通过表达式x>>(16-4)实现。由于x为无符号整数,故空出的左端补0。
(3)将上述两个表达式的值进行按位或运算,即:
y=(x<<4) | (x>>(16-4));
x 0010 1111 0010 0001
x<<4 1111 0010 0001 0000
x>>(16-4) 0000 0000 0000 0010
y 1111 0010 0001 0010
unsigned rol ( unsigned a,int n)
{ unsigned b ;
b=(a<<n) | (a>>(16-n)) ;
return(b);}
计算绝对值
int abs( int x )
{ int y ;
y = x >> 31 ;//二进制最高位
return (x^y)-y ; //or: (x+y)^y
}
位 段
C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,答应在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
位段结构是指结构体成员可以是以位为单位定义存储长度的结构体。
位段结构的定义形式如下:
struct 结构类型名
{
类型 成员 1:长度;
类型 成员2:长度;
……
}
其中,冒号“:”左面的成员称为位段,它是一种特殊的结构成员,冒号右面的长度表示存储位段需要占用字节的位数。
【例】 struct device :
{ unsigned a:1;
unsigned b:2;
unsigned c:4;
int x;
float y;
} data;
定义了结构体变量data,它包含5个成员,它们分别是a,b,c,x,y。
c |
b |
a |
x |
y |
1 4 2 1 16 32
结构变量data的内存分配情况
2 位段的引用
位段是结构体类型的某个成员,因此位端的引用同结构体成员的引用方法相同。
如:data.a=0x01;
data.b=0x0a;
data.i= 12;
printf(“%02x,%02x,%4d”,data.a,data.b,data.c)
输出:01,0a,12
位段也可以用%u、%o等格式符输出。
说明:
1.位段的数据类型必须用unsigned或int类型不能用char和其它类型。有的C编译系统只允许用unsigned型。
未完待续,,,
acm算法模板(3)的更多相关文章
- ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
ACM算法模板 · 一些常用的算法模板-模板合集(打比赛专用)
- ACM算法模板整理
史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...
- acm算法模板(5)
STL 中 sort 函数用法简介 做 ACM 题的时候,排序是一种经常要用到的操作.如果每次都自己写个冒泡之类的 O(n^2) 排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错. ST ...
- acm算法模板(1)
1. 几何 4 1.1 注意 4 1.2 几何公式 4 1.3 多边形 6 1.4 多边形切割 9 1.5 浮点函数 10 1.6 面积 15 1.7 球面 16 1.8 三角形 17 1.9 三维几 ...
- ACM算法模板
旧版模板下载链接: here 新版的模板目前不提供电子版,正在抽时间做一些修正以及添加一些新内容. 新模板如有需要纸质版的,可以自付打印费进行打印.购买链接:https://weidian.com/i ...
- acm算法模板(4)
杂乱小模板 状态压缩dp小技巧 x&-x是取x的最后一个1的位置. x-=x&-x是去掉x的最后一个1. 读入外挂 int nxt_int(){// neg or pos cha ...
- acm算法模板(2)
数学问题: 1.精度计算——大数阶乘 2.精度计算——乘法(大数乘小数) 3.精度计算——乘法(大数乘大数) 4.精度计算——加法 5.精度计算——减法 6.任意进制转换 7.最大公约数.最小公倍数 ...
- ACM - 图论- 网络流 - 算法模板
\(EK\) 算法模板 #include <iostream> #include <queue> #include<string.h> using namespac ...
- hdu 2255 奔小康赚大钱--KM算法模板
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...
随机推荐
- 纯css下拉菜单的制作
通过观察下拉菜单的过程,发现有两种状态,一种是鼠标没有hover时,一种是鼠标hover时. 主菜单hover时,显示子菜单:主菜单没有hover时,不显示子菜单 <!DOCTYPE html& ...
- spring简单事务管理器
事务管理器 <!-- Transaction manager for a single JDBC DataSource --> <bean id="transaction ...
- EF的表连接方法Include()
在EF中表连接常用的有Join()和Include(),两者都可以实现两张表的连接,但又有所不同. 例如有个唱片表Album(AlbumId,Name,CreateDate,GenreId),表中含外 ...
- 如何获取并分析L2CAP包
本文中的分析与软件相关的内容,都是以WinCE中的 Microsoft Bluetooth Core Stack为例进行分析:与协议有关的内容,是基于Bluetooth Core 2.1 + EDR ...
- 【转】JSP中的9大隐藏对象
隐藏对象用在jsp表达式和脚本中,不能直接用在jsp声明中,因为这些隐藏对象是容器在jspservice方法中定义的,在这个方法中定义的变量不能在jsp声明中使用.可以通过参数方法将隐藏对象传递到js ...
- JavaScipt选取文档元素的方法
摘自JavaScript权威指南(jQuery根据样式选择器查找元素的终极方式是 先用getElementsByTagName(*)获取所有DOM元素,然后根据样式选择器对所有DOM元素进行筛选) 选 ...
- [LeetCode]题解(python):091 Decode Ways
题目来源 https://leetcode.com/problems/decode-ways/ A message containing letters from A-Z is being encod ...
- Android开发笔记-加载xml资源
1.Activity获取strings.xml中键的值 需要通过 getResources().getString(R.string.*)方法获得 以“state”为例 String value= g ...
- HTML-002-弹出对话框
日常的网页编程中,弹出对话框经常会以各种形式出现,例如:信息提示框.确认框.新增.修改信息等对话框均是其不同的表现形式. 此文以弹出信息新增对话框进行简要演示,经请参阅! 以下为其对应的结构目录: a ...
- c# 过滤字符串中的重复字符
有字符串"a,s,d,v,a,v",如果想去除其中重复的字符,怎么做? 下面是一个方法,用Hashtable来记录唯一字符,排除重复字符,仅供参考. 1.过滤方法: public ...