这是我参与「第四届青训营 」笔记创作活动的第 3 天
JavaScript 2
引言
function isUnit(m) {
return m[0] === 1 && m[1] === 0 && m[2] === 0
&& m[3] === 1 && m[4] === 0 && m[5] === 0;
}
为什么不使用循环?
- 要结合场景, 循环不一定效率高
Leftpad 事件
function leftpad(str, len, ch) {
str = String(str);
var i = -1;
if (!ch && ch !== 0) ch = ' ';
len = len - str.length;
while (++i < len) {
str = ch + str;
}
return str;
}
槽点
- NPM 模块粒度
- 代码风格
- 代码质量 / 效率
优化代码
function leftpad(str, len, ch) {
str = "" + str;
const padLen = len - str.length;
if(padLen <= 0) {
return str;
}
return (""+ch).repeat(padLen)+str;
}
repeat 使用快速乘, 效率要比循环高
案例: 交通灯
版本一
函数嵌套, 可读性差
版本二
数据抽象
- 将灯的情况进行抽象出来
版本三
过程抽象
- 灵活性更高
版本四
异步 + 函数式
- 可读性高
案例: 判断是否是 4 的幂
版本一
取模除 4
版本二
操作改为位操作
版本三
位操作, n & (n - 1) 的妙用
版本四
正则匹配, 效率不高, 但可读性高
案例: 洗牌
版本一
使用 sort - random 去排序
- 不随机, 各数字概率不一样
版本二
随机找一个, 然后从剩下的里面找
版本三
将版本二改成生成器, 一次只返回一张
案例: 分红包
切西瓜法
- 将西瓜随机一分为二
- 每次挑选最大的一个西瓜快继续随机一分为二
- 直到分成需要的数量
抽牌法
- 将金额换成整数, 然后从里面插入 n - 1 个值
- 每个区间内对应一个数组
总结
这次课的主要内容涉及一些代码的优化, 偏向于算法内容
快速乘
在 Leftpad 事件中, 在 repeat 中使用到了快速乘
- 其主要思路是合并
- 对于 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2
- 优化为, 4 + 4 + 4 + 4, 进而 8 + 8 , 最后为 16
- 这样可以减少循环次数, 加快运算次数
- 同样原理的还有快速幂
n & (n - 1)
巧妙的位运算的使用, 可以去掉数字 n 转化为二进制后的最低位的一个 1
-
常见的还有 lowbit 的使用
- n & -n
- 可以得到 n 转换为二进制后的最低位的 1 对应的数的大小