Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
214 views
in Technique[技术] by (71.8m points)

vue 源码中为什么这么写 这个repeat 函数?

  var repeat = function (str, n) {
    var res = '';
    while (n) {
      if (n % 2 === 1) { res += str; }
      if (n > 1) { str += str; }
      n >>= 1;
    }
    return res
  };

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

这样写可以把循环次数从 n 次优化到 log2(n) 次。

把 n 写成二进制形式,从低位到高位遍历,每移动一位意味着基数翻一倍,这一位为0意味着不计入结果,为1意味着计入结果。

  var repeat = function (str, n) {
    // 结果存放的地方
    var res = '';
    while (n) { // n 没到达 0 则循环
      
      //当前位是0是1? 是 1 的话计入结果,str 是当前位的基数
      if (n % 2 === 1) { res += str; }
      
      //还有下一位吗?有的话 str 翻倍即为下一位的基数 
      if (n > 1) { str += str; }
      
      //移动到下一位
      n >>= 1;
    }
    return res
  };

比如要循环字符 “abc” 11 次,11 写成二进制:1011

二进制位1011
基数8421
基数对应字符串abcabcabcabcabcabcabcabcabcabcabcabcabcabcabc

基数对应字符串刚好是上一次的翻倍,这就是 if (n > 1) { str += str; } 的意思。因为 11 = 1 + 2 + 8,所以循环 11 次的字符串就等于列对应的底下的字符串相加。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...