通过位运算来解决一些算法题
在刷pat的1073 多选题常见计分法题目时,发现如果需要判断每一个学生对应每道题的多选题是否错选,漏选,以及选对是比较麻烦的一件事,因为这涉及到两个集合的判断,判断一个集合是否是另一个集合的子集(即漏选,得一半的分),或者说两个集合是否完全相等(即题目得满分)。
刚开始通过set容器来保存每一道题的正确答案,以及学生选择的答案,然后比较两个集合的大小,大小一致则for循环判断每一个元素是否都存在。结果发现这种思路过于复杂,且易超时。
联想到每一个选项是否一致,可以通过异或运算判断两个集合,如果结果为0则得满分,否则就是错选或者漏选,错选漏选通过或运算来判断是否能够得到正确集合,如果可以则是漏选,如果不能则说明是错选。
在完整的实现这道题之前,先来学习一下位运算的基础。
1.常见的位运算
常见的位运算有6个,见如下表格:
Operators | Meaning of operators |
---|---|
& | Bitwise AND,按位与 |
| | Bitwise OR,按位或 |
^ | Bitwise XOR,按位异或 |
~ | Bitwise complement,按位取反 |
<< | Shift left,左移 |
>> | Shift right,右移 |
1.1按位与
运算举例,对12和25进行按位与操作:
12 = 00001100 (In Binary) 25 = 00011001 (In Binary) Bit Operation of 12 and 25 00001100 & 00011001 ________ 00001000 = 8 (In decimal)
当且仅当,两个二进制位都为1时,结果才为1
代码举例:
#include <stdio.h> int main() { int a = 12, b = 25; printf("Output = %d", a&b); return 0; }
Output:
Output = 8
1.2按位或
运算举例,对12和25进行按位或操作:
12 = 00001100 (In Binary) 25 = 00011001 (In Binary) Bitwise OR Operation of 12 and 25 00001100 | 00011001 ________ 00011101 = 29 (In decimal)
当且仅当,两个二进制位都为0时,结果才为0,其它情况都为1
代码举例:
#include <stdio.h> int main() { int a = 12