起由 最近由于 996.icu 事件,才知道 GitHub 排行前十的 repo 中有这样一个项目。于是就刷起来了
题 & 解 1. 找出最长单词 在句子中找出最长的单词,并返回它的长度。函数的返回值应该是一个数字。
1 2 3 4 5 6 7 findLongestWord("The quick brown fox jumped over the lazy dog" ) 应该返回一个数字 findLongestWord("The quick brown fox jumped over the lazy dog" ) 应该返回 6. findLongestWord("May the force be with you" ) 应该返回 5. findLongestWord("Google do a barrel roll" ) 应该返回 6. findLongestWord("What is the average airspeed velocity of an unladen swallow" ) 应该返回 8. findLongestWord("What if we try a super-long word such as otorhinolaryngology" ) 应该返回 19.
解答:
1 2 3 4 5 function findLongestWord (str ) { const arr = str.split(' ' ).map(word => word.length); return Math .max(...arr); }
2. 句中单词首字母大写 确保字符串的每个单词首字母都大写,其余部分小写。像’the’和’of’这样的连接符同理。
1 2 3 4 5 titleCase("I'm a little tea pot" ) 应该返回一个字符串 titleCase("I'm a little tea pot" ) 应该返回 "I'm A Little Tea Pot" . titleCase("sHoRt AnD sToUt" ) 应该返回 "Short And Stout" . titleCase("HERE IS MY HANDLE HERE IS MY SPOUT" ) 应该返回 "Here Is My Handle Here Is My Spout" .
解答:
1 2 3 4 function titleCase (str ) { return str.toLowerCase().split(' ' ).map(word => word.replace(word[0 ], word[0 ].toUpperCase())).join(' ' ); }
3. 找出多个数组中的最大数 右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组。 提示:你可以用for循环来迭代数组,并通过arr[i]的方式来访问数组的每个元素。
1 2 3 4 largestOfFour([[4 , 5 , 1 , 3 ], [13 , 27 , 18 , 26 ], [32 , 35 , 37 , 39 ], [1000 , 1001 , 857 , 1 ]]) 应该返回一个数组 largestOfFour([[13 , 27 , 18 , 26 ], [4 , 5 , 1 , 3 ], [32 , 35 , 37 , 39 ], [1000 , 1001 , 857 , 1 ]]) 应该返回 [27 ,5 ,39 ,1001 ]. largestOfFour([[4 , 9 , 1 , 3 ], [13 , 35 , 18 , 26 ], [32 , 35 , 97 , 39 ], [1000000 , 1001 , 857 , 1 ]]) 应该返回 [9 , 35 , 97 , 1000000 ].
解答:
1 2 3 4 5 function largestOfFour (arr ) { const result = []; arr.forEach(child => result.push(Math .max.call(...child))); return result; }
你以为对了吗???? 呵呵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 const array= [1000000 ,1001 ];Math .max.call(...array);所以,解答的结果中为: [9 , 35 , 97 , 1001 ],与预期 [9 , 35 , 97 , 1000000 ] 不符 Math .max.call(null , 1001 ) 等价于 Math .max(1001 ) function largestOfFour (arr ) { const result = []; arr.forEach(child => result.push(Math .max(...child))); return result; } function largestOfFour (arr ) { const result = []; arr.forEach(child => { if (child.length > 1 ) { result.push(Math .max(...child)) } if (child.length === 1 ) { result.push(child); } if (result.length === 0 ) { return ; } }); return result; }
4. 检查字符串结尾 判断一个字符串(str)是否以指定的字符串(target)结尾。 如果是,返回true;如果不是,返回false。
1 2 3 4 5 6 7 8 confirmEnding("Bastian" , "n" ) 应该返回 true . confirmEnding("Connor" , "n" ) 应该返回 false . confirmEnding("Walking on water and developing software from a specification are easy if both are frozen" , "specification" ) 应该返回 false . confirmEnding("He has to give me a new name" , "name" ) 应该返回 true . confirmEnding("He has to give me a new name" , "me" ) 应该返回 true . confirmEnding("He has to give me a new name" , "na" ) 应该返回 false . confirmEnding("If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing" , "mountain" ) 应该返回 false .
解答:
1 2 3 4 5 6 7 8 function confirmEnding (str, target ) { if (target.length === 1 ) { return str[str.length-1 ] === target; } const arr = str.split(' ' ); return (arr[arr.length-1 ].indexOf(target) > 0 ) || arr[arr.length-1 ] === target; }
5. 重复输出字符串 (重要的事情说3遍)重复一个指定的字符串 num次,如果num是一个负数则返回一个空字符串。
1 2 3 4 5 6 7 repeat("*" , 3 ) 应该返回 "***" . repeat("abc" , 3 ) 应该返回 "abcabcabc" . repeat("abc" , 4 ) 应该返回 "abcabcabcabc" . repeat("abc" , 1 ) 应该返回 "abc" . repeat("*" , 8 ) 应该返回 "********" . repeat("abc" , -2 ) 应该返回 "" .
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function repeat (str, num ) { return num > 0 ? str.repeat(num) : '' ; } function repeat (str, num ) { if (num > 0 ) { let result = '' ; for (var i = 0 ;i< num;i++) { result += str; } return result; } else {return '' } }
6. 截断字符串 (用瑞兹来截断对面的退路) 如果字符串的长度比指定的参数num长,则把多余的部分用…来表示。 切记,插入到字符串尾部的三个点号也会计入字符串的长度。但是,如果指定的参数num小于或等于3,则添加的三个点号不会计入字符串的长度。
1 2 3 4 5 6 7 truncate("A-tisket a-tasket A green and yellow basket" , 11 ) 应该返回 "A-tisket..." . truncate("Peter Piper picked a peck of pickled peppers" , 14 ) 应该返回 "Peter Piper..." . truncate("A-tisket a-tasket A green and yellow basket" , "A-tisket a-tasket A green and yellow basket" .length) 应该返回 "A-tisket a-tasket A green and yellow basket" . truncate("A-tisket a-tasket A green and yellow basket" , "A-tisket a-tasket A green and yellow basket" .length + 2 ) 应该返回 "A-tisket a-tasket A green and yellow basket" . truncate("A-" , 1 ) 应该返回 "A..." . truncate("Absolutely Longer" , 2 ) 应该返回 "Ab..." .
解答:
1 2 3 4 5 6 7 8 9 function truncate ( ) { if (str.length > num) { return str.substr(0 ,num-3 ) + `...` ; } if (num <= 3 ) { return str.substr(0 ,num) + '...' ; } }
7. 猴子吃香蕉, 分割数组 (猴子吃香蕉可是掰成好几段来吃哦) 把一个数组arr按照指定的数组大小size分割成若干个数组块 例如:chunk([1,2,3,4],2)=[[1,2],[3,4]]; chunk([1,2,3,4,5],2)=[[1,2],[3,4],[5]];
1 2 3 4 5 6 7 chunk(["a" , "b" , "c" , "d" ], 2 ) 应该返回 [["a" , "b" ], ["c" , "d" ]]. chunk([0 , 1 , 2 , 3 , 4 , 5 ], 3 ) 应该返回 [[0 , 1 , 2 ], [3 , 4 , 5 ]]. chunk([0 , 1 , 2 , 3 , 4 , 5 ], 2 ) 应该返回 [[0 , 1 ], [2 , 3 ], [4 , 5 ]]. chunk([0 , 1 , 2 , 3 , 4 , 5 ], 4 ) 应该返回 [[0 , 1 , 2 , 3 ], [4 , 5 ]]. chunk([0 , 1 , 2 , 3 , 4 , 5 , 6 ], 3 ) 应该返回 [[0 , 1 , 2 ], [3 , 4 , 5 ], [6 ]]. chunk([0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ], 4 ) 应该返回 [[0 , 1 , 2 , 3 ], [4 , 5 , 6 , 7 ], [8 ]].
解答
1 2 3 4 5 6 7 8 9 10 11 12 function chunk (arr, size ) { if (arr.length < size) { return arr; } const result = []; for (var i=0 ;i< arr.length;i=i+size) { result.push(arr.slice(i,i+size)) } return result; }
这道题一时半会我也没有思路,网上搜索的答案。 针对该类问题,大概的思路就是: 通过迭代不断简化问题的复杂度,在每次迭代中处理细化后的小 case take a case:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const arr = [1 ,2 ,3 ];const size = 2 ;i = 0 ; i + size = 0 + 2 = 2 ; arr.slice(0 ,2 ) => [1 ,2 ] i = 之前循环末尾语句的计算结果 i = 2 ; i + size = 2 + 2 = 4 ; arr.slice(2 ,4 ) => [3 ] */
8. 截断数组 返回一个数组被截断n个元素后还剩余的元素,截断从索引0开始。
1 2 3 4 5 6 7 slasher([1 , 2 , 3 ], 2 ) 应该返回 [3 ]. slasher([1 , 2 , 3 ], 0 ) 应该返回 [1 , 2 , 3 ]. slasher([1 , 2 , 3 ], 9 ) 应该返回 []. slasher([1 , 2 , 3 ], 4 ) 应该返回 []. slasher(["burgers" , "fries" , "shake" ], 1 ) 应该返回 ["fries" , "shake" ]. slasher([1 , 2 , "chicken" , 3 , "potatoes" , "cheese" , 4 ], 5 ) 应该返回 ["cheese" , 4 ].
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function slasher (arr, howMany ) { if (arr.length < howMany) { return []; } arr.splice(0 , howMany); return arr; } - Array .prototype.push() - Array .prototype.unshift() - Array .prototype.pop() - Array .prototype.shift() - Array .prototype.sort()
9. 比较字符串 (蛤蟆可以吃队友,也可以吃对手)如果数组第一个字符串元素包含了第二个字符串元素的所有字符,函数返回true。 举例,[“hello”, “Hello”]应该返回true,因为在忽略大小写的情况下,第二个字符串的所有字符都可以在第一个字符串找到。 [“hello”, “hey”]应该返回false,因为字符串”hello”并不包含字符”y”。 [“Alien”, “line”]应该返回true,因为”line”中所有字符都可以在”Alien”找到。
1 2 3 4 5 6 7 8 9 mutation(["hello" , "hey" ]) 应该返回 false . mutation(["hello" , "Hello" ]) 应该返回 true . mutation(["zyxwvutsrqponmlkjihgfedcba" , "qrstu" ]) 应该返回 true . mutation(["Mary" , "Army" ]) 应该返回 true . mutation(["Mary" , "Aarmy" ]) 应该返回 true . mutation(["Alien" , "line" ]) 应该返回 true . mutation(["floor" , "for" ]) 应该返回 true . mutation(["hello" , "neo" ]) 应该返回 false .
10. 比较字符串 (蛤蟆可以吃队友,也可以吃对手) 如果数组第一个字符串元素包含了第二个字符串元素的所有字符,函数返回true。 举例,[“hello”, “Hello”]应该返回true,因为在忽略大小写的情况下,第二个字符串的所有字符都可以在第一个字符串找到。 [“hello”, “hey”]应该返回false,因为字符串”hello”并不包含字符”y”。 [“Alien”, “line”]应该返回true,因为”line”中所有字符都可以在”Alien”找到。
1 2 3 4 5 6 7 8 9 mutation(["hello" , "hey" ]) 应该返回 false . mutation(["hello" , "Hello" ]) 应该返回 true . mutation(["zyxwvutsrqponmlkjihgfedcba" , "qrstu" ]) 应该返回 true . mutation(["Mary" , "Army" ]) 应该返回 true . mutation(["Mary" , "Aarmy" ]) 应该返回 true . mutation(["Alien" , "line" ]) 应该返回 true . mutation(["floor" , "for" ]) 应该返回 true . mutation(["hello" , "neo" ]) 应该返回 false .
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 function mutation (arr ) { const prev = arr[0 ].toLowerCase().split('' ).sort().join('' ); const next = arr[1 ].toLowerCase().split('' ).sort().join('' ); let result = true ; for (var i =0 ;i<next.length;i++) { if (!prev.includes(next[i])) { result = false ; } } return result; } function mutation (arr ) { const accumulator = (acc, prev, index, arr ) => { if (arr[index + 1 ]) { prev = prev.toLowerCase(); const next = arr[index + 1 ].toLowerCase(); for (var i = 0 ; i < next.length; i++) { if (!prev.includes(next[i])) { return false ; } acc = true ; } } return acc; }; return arr.reduce(accumulator, true ); }
11. 过滤数组假值 (真假美猴王)删除数组中的所有假值。 在JavaScript中,假值有false、null、0、””、undefined 和 NaN。
1 2 3 4 5 bouncer([7 , "ate" , "" , false , 9 ]) 应该返回 [7 , "ate" , 9 ]. bouncer(["a" , "b" , "c" ]) 应该返回 ["a" , "b" , "c" ]. bouncer([false , null , 0 , NaN , undefined , "" ]) 应该返回 []. bouncer([1 , null , NaN , 2 , undefined ]) 应该返回 [1 , 2 ].
解答:
1 2 3 4 5 function bouncer (arr ) { return arr.filter(member => Boolean (member)); }
摧毁数组 金克斯的迫击炮!实现一个摧毁(destroyer)函数,第一个参数是待摧毁的数组,其余的参数是待摧毁的值。1 2 3 4 5 6 7 destroyer([1 , 2 , 3 , 1 , 2 , 3 ], 2 , 3 ) 应该返回 [1 , 1 ]. destroyer([1 , 2 , 3 , 5 , 1 , 2 , 3 ], 2 , 3 ) 应该返回 [1 , 5 , 1 ]. destroyer([3 , 5 , 1 , 2 , 2 ], 2 , 3 , 5 ) 应该返回 [1 ]. destroyer([2 , 3 , 2 , 3 ], 2 , 3 ) 应该返回 []. destroyer(["tree" , "hamburger" , 53 ], "tree" , 53 ) 应该返回 ["hamburger" ].
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function destroyer (arr, ...rest ) { const params = Array .from(rest); params.map(member => { arr = arr.filter(item => item !== member); }); return arr; } function destoryer (arr ) {const brr = JSON .parse(JSON .stringfy(arr));brr.shift(); const params = Array .from(brr); params.map(member => { arr = arr.filter(item => item !== member); }); return arr; }
13. 数组排序并找出元素索引 我身在何处? 先给数组排序,然后找到指定的值在数组的位置,最后返回位置对应的索引。 举例:where([1,2,3,4], 1.5) 应该返回 1。因为1.5插入到数组[1,2,3,4]后变成[1,1.5,2,3,4],而1.5对应的索引值就是1。 同理,where([20,3,5], 19) 应该返回 2。因为数组会先排序为 [3,5,20],19插入到数组[3,5,20]后变成[3,5,19,20],而19对应的索引值就是2。
1 2 3 4 5 6 7 8 where([10 , 20 , 30 , 40 , 50 ], 35 ) 应该返回 3. where([10 , 20 , 30 , 40 , 50 ], 30 ) 应该返回 2. where([40 , 60 ], 50 ) 应该返回 1. where([3 , 10 , 5 ], 3 ) 应该返回 0. where([5 , 3 , 20 , 3 ], 5 ) 应该返回 2. where([2 , 20 , 10 ], 19 ) 应该返回 2. where([2 , 5 , 10 ], 15 ) 应该返回 3.
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function where (arr, num ) { arr.sort((a,b ) => a-b); let insetIndex = 0 ; if (arr.every(member => member <= num)) { insetIndex = arr.length; } else if (arr.every(member => member >= num)) { insetIndex = 0 ; } else { insetIndex = arr.findIndex(member => member >= num); } return insetIndex; }
14. 凯撒密码 (让上帝的归上帝,凯撒的归凯撒)下面我们来介绍风靡全球的凯撒密码Caesar cipher,又叫移位密码。 移位密码也就是密码中的字母会按照指定的数量来做移位。 一个常见的案例就是ROT13密码,字母会移位13个位置。由’A’ ↔ ‘N’, ‘B’ ↔ ‘O’,以此类推。 写一个ROT13函数,实现输入加密字符串,输出解密字符串。
什么是凯撒密码?一张图说明: 下图搬运自:https://img-blog.csdn.net/20180826085456567?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5ncWl1bWluZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
图片搬运自https://img-blog.csdn.net/20180826085456567?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5ncWl1bWluZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
我的理解: 简单来说,凯撒密码的规则就是,加密和揭秘双方以一个数字作为密钥,来约定每个字母的位移顺序。例如,密钥为3时,A => D, B=> E … X => A (因为X的 charCodeAt +3 已经超过了 Z,不符合规则,因此需要 先减去一个 循环的周期 26,再按照密钥+3)
不 BB 了, show you code
1 2 3 4 `X` .charCodeAt(0 ) = 88 ;String .fromCharCode(88 +3 ); String .fromCharCode(88 -26 +3 );
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 function rot13 (str ) { const stringArrays = str.split(' ' ).filter(member => !!member); const parseResult = stringArrays.map(word => { return Array .from(word).map(charator => { const ZCode = 'Z' .charCodeAt(0 ); let current = charator.charCodeAt(0 ); if (current < 65 || current > ZCode) { return charator; } else { const dest = (charator.charCodeAt(0 ) + 13 ) > ZCode ? (charator.charCodeAt(0 ) -26 + 13 ): charator.charCodeAt(0 ) + 13 ; return String .fromCharCode(dest); } }).join('' ); }).join(' ' ); return parseResult; } if (current < 65 || current > ZCode) { return charator; } 可以使用 String .match(/\w/g ) 来命中为数组,从而过滤掉非字母的标点符号
总结 这些算法都是最最最最最基本的算法,然而在解决这些问题中,还是出现了卡壳的地方。 算法还是得多练,人脑的逻辑思维,就得靠大量算法来优化和调教~ keep moving !
😘觉得文章有用?点击下方打赏,鼓励作者更好的写作!