这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
JavaScript课程笔记(下)
一、重点内容
- 代码写作关注事项
- left-pad 事件背后的代码规范
- 代码实践1 - 交通灯
- 代码实践2 - 洗牌
- 代码实践3 - 分红包
二、详细知识点
1、写代码最应当关注的是什么?
- 风格
- 效率
- 约定
- 使用场景
- 设计
2、left-pad 事件是什么?
- leftpad库,多个数字为了保持整齐,前面补齐0,使数字的位数一样。
- 但下架了之后不能用,遭到人们吐槽。
- 原本的这个函数时间复杂度n,性能不好。
- 有人改写优化,更简洁,性能更好,时间复杂度O(n)。
- 但其实位数补齐0,由于使用量小,因此性能提高意义不大。
3、repeat()快速幂
repeat()方法构造并返回一个新字符串,该字符串包含调用它的字符串的指定数量的副本,并连接在一起。
【实例】 输出5个* 只需要执行3次
原理:从n末尾判断每一位的值,除以2,如果余数1,结果拼接一个string,判断n的值>1则string拼接为原来的两倍长度,然后n右移一位。
4、实践1 - 交通灯
需要进行数据抽象封装 状态抽象-->过程抽象-->异步+函数式
5、判断是否是4的幂
4的幂数字特点,二进制:1后面跟n个00
(1)直接判断
(2)& 0b11 即二进制&11 ,00&11 假,除00外的其他&11 真 直接返回假
(3)① num & (num-1) == 0,如果符合条件,证明这个二进制只有一个1(某一位上)
如果不等于零,表示高位数字上有重合的,而这不符合4的幂的规则(原因是由多个1)
例如n=1101011000(二进制,十进制也一样),则n-1=1101010111。n&(n-1)=1101010000
②确定只有一个1后,再确定二进制偶数位不为1,并上01010...10这样的数字不能为1
并根据JS位数,并上的数字为0xAAAAAAAAAAAA (13个A,16进制)
(4)正则表达式直接匹配
6、实践2 - 洗牌
(1)错误算法
大于0.5,-1交换位置,否则1不交换位置
这个算法,分布不均匀。越小的数字抽中概率越高
验证:越小的数字,排在靠前的几率越大
(2)正确算法
随机取一张,拿出来换到最后位置,剩下之中再随机取一张,拿出来换到倒数第二位置
保证每张牌再任何位置抽到的概率均等
P = (k-1)/k * 1/(k-1) = 1/k
(3)改进-使用生成器
没有必要全部洗完牌,for循环不用跑完,因为只取1张牌(或某几张牌)
7、实践3 - 分红包
输入红包金额和红包数量,随机分配红包
注意:不能完全随机,因为如果够分的情况下,至少要每人0.01
(1)切西瓜法
每次切最大的那块
算法特点,结果倾向于均匀,不够刺激
时间复杂度O(m*n),不很好,一般分的人少所以也可以
(2)抽牌法
100元10人,看成10000的数列:0,1,2,9999
其中插入9个分隔符,例如第一个分隔符49,第一个人分0.49,第二个分隔符199,第二个人分1.5,以此类推
用之前讲到的生成器取9个随机数,排序,减去前一个值就是最终的金额
时间复杂度O(n),但是空间复杂度不好(10000数列)
三、个人总结
1、写好代码需要注意:
- 可读性高
- 结构清晰
- 可扩展(方便维护)
- 代码风格统一
- 低复杂性
- 简洁
2、学好数学很重要
前端也需要很好的数学思维,实现更好的算法,使程序效率更高。