JavaScript 面试题:重复输出一个给定的字符串

guez5899 8年前
   <p style="text-align:center"><img src="https://simg.open-open.com/show/3e43f0767c79fb0c71770127c4c3675c.jpg"></p>    <p>其实这是可以作为一道很好的面试题,可以考察开发人员的综合能力。</p>    <h3><strong>面试题:</strong></h3>    <p>重复输出一个给定的字符串( str 第一个参数)n 次 ( num 第二个参数),如果第二个参数 num 不是正数的时候,返回空字符串。</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(str, num) {    return str;  }  repeatStringNumTimes("abc", 3);</code></pre>    <p>提供测试情况:</p>    <pre>  <code class="language-javascript">repeatStringNumTimes("*", 3) //应该返回 "***".  repeatStringNumTimes("abc", 3) //应该返回 "abcabcabc".  repeatStringNumTimes("abc", 4) //应该返回 "abcabcabcabc".  repeatStringNumTimes("abc", 1) //应该返回 "abc".  repeatStringNumTimes("*", 8) //应该返回 "********".  repeatStringNumTimes("abc", -2) //应该返回 "".</code></pre>    <h3><strong>解题思路:</strong></h3>    <p>我将介绍三种方法:</p>    <ol>     <li>使用 `while` 循环</li>     <li>使用递归</li>     <li>使用ES6 `repeat()`</li>    </ol>    <p><strong>方法1:通过 `while` 循环重复输出一个字符串</strong></p>    <p>这可能是最常规的解题思路。 while 语句只要指定的条件计算结果为 true 的时候,就执行其语句。 while 语句结构大概是这样的:</p>    <pre>  <code class="language-javascript">while (condition)    statement</code></pre>    <p>在每次通过循环之前计算条件结果。如果条件为 true ,则执行语句。如果条件为 false ,则执行继续 while 循环之后的任何语句。</p>    <p>只要条件为 true ,语句就会执行。 这里是解决方案:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    // 第1步. 常见一个空字符,用来寄存重复的字符串    var repeatedString = "";      // 第2步. 设置 while 循环的条件为(times > 0) 作为检查    while (times > 0) { // 只要 times 大于 0, 语句就会执行      // 执行语句 statement      repeatedString += string; // 等价于 repeatedString = repeatedString + string;       times--; // 递减,等价于 times = times - 1;     }    /* while循环逻辑            条件        T/F    repeatedString += string   结果          次数      1th   (3 > 0)    true    "" + "abc"                "abc"          2      2th   (2 > 0)    true    "abc" + "abc"             "abcabc"       1      3th   (1 > 0)    true    "abcabc" + "abc"          "abcabcabc"    0      4th   (0 > 0)    false      }    */        // 第3步. 返回重复字符串    return repeatedString; // "abcabcabc"  }    repeatStringNumTimes("abc", 3);</code></pre>    <p>去掉注释后:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    var repeatedString = "";    while (times > 0) {      repeatedString += string;      times--;    }    return repeatedString;  }  repeatStringNumTimes("abc", 3);</code></pre>    <p>好,轻松完成!不过这里还可以有几个变种:</p>    <p>对于老前端来说,首先一个可能会将字符串拼接,修改为 数组 join() 拼接字符串,例如:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    var repeatedArr = []; //    while (times > 0) {      repeatedArr.push(string);      times--;    }    return repeatedArr.join("");  }  repeatStringNumTimes("abc", 3)</code></pre>    <p>很多老前端都有用数组 join() 拼接字符串的“情怀”,因为很早以前普遍认为数组 join() 拼接字符串比字符串 + 拼接速度要快得多。不过现在未必,例如,V8 下 + 拼接字符串,要比数组 join() 拼接字符串快。我用这两个方法测试了3万次重复输出,只相差了几毫秒。</p>    <p>另一个变种可以用 for 循环:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    var repeatedString = "";    for(var i = 0; i < times ;i++) {      repeatedString += string;    }    return repeatedString;  }  repeatStringNumTimes("abc", 3)</code></pre>    <p><strong>方法2:通过条件判断和递归重复输出一个字符串</strong></p>    <p>递归是一种通过重复地调用函数本身,直到它达到达结果为止的迭代操作的技术。为了使其正常工作,必须包括递归的一些关键特征。</p>    <p>第一种是基本情况:一个语句,通常在一个条件语句(如 if )中,停止递归。</p>    <p>第二种是递归情况:调用递归函数本身的语句。</p>    <p>这里是解决方案:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    // 步骤1.检查 times 是否为负数,如果为 true 则返回一个空字符串     if (times < 0) {      return "";    }        // 步骤2.检查times是否等于1,如果是,返回字符串本身。    if (times === 1) {      return string;    }        // 步骤3. 使用递归    else {      return string + repeatStringNumTimes(string, times - 1); // return "abcabcabc";    }    /*       递归方法的第一部分你需要记住,你不会只调用一次,您将有好几个嵌套调用                   times       string + repeatStringNumTimes(string, times - 1)        1st call   3           "abc" + ("abc", 3 - 1)        2nd call   2           "abc" + ("abc", 2 - 1)        3rd call   1           "abc" => if (times === 1) return string;        4th call   0           ""   => if (times <= 0) return "";      递归方法的第二部分        4th call will return      ""        3rd call will return     "abc"        2nd call will return     "abc"        1st call will return     "abc"      最后调用是串联所有字符串      return "abc" + "abc" + "abc"; // return "abcabcabc";    */  }  repeatStringNumTimes("abc", 3);</code></pre>    <p>去掉注释后:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    if(times < 0)       return "";    if(times === 1)       return string;    else       return string + repeatStringNumTimes(string, times - 1);  }  repeatStringNumTimes("abc", 3);</code></pre>    <p><strong>方法3:使用ES6 `repeat()` 方法重复输出一个字符串</strong></p>    <p>这个解决方案比较新潮,您将使用 String.prototype.repeat() 方法:</p>    <p>repeat() 方法构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。 这个方法有一个参数 count 表示重复次数,介于0和正无穷大之间的整数 : [0, +∞) 。表示在新构造的字符串中重复了多少遍原字符串。重复次数不能为负数。重复次数必须小于 infinity,且长度不会大于最长的字符串。</p>    <p>这里是解决方案:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    //步骤1.如果 times 为正数,返回重复的字符串    if (times > 0) { // (3 > 0) => true      return string.repeat(times); // return "abc".repeat(3); => return "abcabcabc";    }        //Step 2. Else 如果times是负数,如果为true则返回一个空字符串    else {      return "";    }  }    repeatStringNumTimes("abc", 3);</code></pre>    <p>去掉注释后:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    if (times > 0)      return string.repeat(times);    else      return "";  }  repeatStringNumTimes("abc", 3);</code></pre>    <p>您可以使用三元表达式作为 if/else 语句的快捷方式,如下所示:</p>    <pre>  <code class="language-javascript">function repeatStringNumTimes(string, times) {    times > 0 ? string.repeat(times) : "";  }  repeatStringNumTimes("abc", 3);</code></pre>    <p>面试官可能会根据欣赏这样的简洁代码。</p>    <p> </p>    <p>来自:http://www.css88.com/archives/7045</p>    <p> </p>