# 位操作:省时间,省空间,提效率

# 三种常见的位操作
记得我刚玩Linux系统的时候,经常会遇到权限不足的问题,然后一个chmod 777 命令就稿定了。这个命令背后做了啥事呢?我们还得从Linux文件聊起
Linux下一个文件一经创建,就具有三种访问方式
- 读,可以显示该文件的内容
- 写,可以编辑或删除它
- 执行,如果该文件是一个shell脚本或者程序
按照所正对的用户,文件的权限可以分为三类
- 文件属主,创建该文件的用户
- 同组用户,文件属主所在用户组的任何用户
- 其他用户,不包含文件属主的其他用户组中的用户
[root@VM_0_14_centos ~]# ll
total 32
drwxr-xr-x 4 root root 4096 Nov 28 00:09 group-chat
drwxr-xr-x 5 root root 4096 Oct 16 11:41 new-blog
-rwxr--r-- 1 root root 2303 Sep 17 11:31 start_sb_app.sh
分析一下命令的结果
| 输出 | 解释 |
|---|---|
| total 32 | 该目录中所有文件所占的空间 |
| drwxr-xr-x | d表示文件的类型,rwxr-xr-x9个字符表示文件的访问权限 |
| 4 | 该文件硬链接的数目 |
| root | 文件的属主 |
| root | 文件属主root所在的缺省组(也叫做root) |
| 28 | 用字节来表示的文件长度 |
| Nov 28 00:09 | 文件的更新时间 |
| group-chat | 文件名 |
rwxr-xr-x9个字符表示文件的访问权限,这9个字符可以分为三组 rwx:文件属主权限 r-x:同组用户权限 r-x:其他用户权限
rwx位置上的-表示相应的访问权限被禁止。举个例子
| 权限 | 所代表的的含义 |
|---|---|
| r-- --- --- | 文件属主可读,但不能写或执行 |
| rwx r-- r-- | 文件属主可读,写,执行,同组和其他用户只可读 |
| rwx rwx rwx | 所有人可读,写,执行 |
用二级制数字的0和1来表示用户的权限,这个思想很牛逼,用图演示一下
当用户同时有读写执行权限时,二进制为是111,转为10进制就是7,所以777就表示文件属主,同组用户和其他用户都拥有读写执行权限
举几个例子演示一下
| 命令 | 结果 | 含义 |
|---|---|---|
| chmod 777 myfile | rwx rwx rwx | 赋予所有用户读,写,执行权限 |
| chmod 644 myfile | rw-- r-- r-- | 赋予文件属组读和写的权限,所有其他用户读权限 |
| chmod 444 myfile | r-- r-- r-- | 赋予所有用户读权限 |
这种用二进制的位来表示状态的思想是不是很牛逼?即节省空间,效率又高
二进制常见的操作有与,或,非,异或
与操作(有0出0,全1出1)
| 数字 | 二级制 |
|---|---|
| A | 1 0 1 0 |
| B | 1 1 0 0 |
| A & B | 1 0 0 0 |
或操作(有1出1;全0出0)
| 数字 | 二级制 |
|---|---|
| A | 1 0 1 0 |
| B | 1 1 0 0 |
| A | B | 1 1 1 0 |
非操作(有1出0;有0出1)
| 数字 | 二级制 |
|---|---|
| A | 1 0 1 0 |
| ~A | 0 1 0 1 |
异或操作(同为0,异为1)
| 数字 | 二级制 |
|---|---|
| A | 1 0 1 0 |
| B | 1 1 0 0 |
| A ^ B | 0 1 1 0 |
利用这些特性,我们可以做很多有趣的事情。
# 二进制骚操作
# 判断奇偶
// 常规操作
if (n % 2 == 1)
// 骚操作
if (n & 1 == 1)
当一个数为奇数时,二进制的最后以为一定为1,所有n & 1 == 1一定为奇数,否则为偶数
# 判断一个数是否是2的指数
我们最常想到的就是这个数不断除以2,如果最后结果是1,则是2的指数,否则不是
2^0 = 1 = 0001
2^1 = 2 = 0010
2^2 = 4 = 0100
可以看到如果一个数是2的指数,只有最高位是1,其他都是0,我们就可以利用这个特性
// 当 n & (n - 1) == 0 为0时说明这个数是2的指数
n & (n - 1) == 0
# 查找只出现一次的元素
给定一个数组nums[],除了一个元素只出现一次外,其余元素都出现了2次,找出这个只出现了一次的元素。
2个相同的元素进行异或操作,会变为0,所以对数组中的所有元素进行异或操作,最后的值即为出现了一次的元素
class Solution {
public int singleNumber(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum ^= nums[i];
}
return sum;
}
}