JavaScript课程笔记(下) | 青训营笔记

115 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天

JavaScript课程笔记(下)

一、重点内容

  1. 代码写作关注事项
  2. left-pad 事件背后的代码规范
  3. 代码实践1 - 交通灯
  4. 代码实践2 - 洗牌
  5. 代码实践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、学好数学很重要

前端也需要很好的数学思维,实现更好的算法,使程序效率更高。