在刷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