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>