1.很多人都使用过牛客网这个在线编程网站,下面是自己做的该项所有练习分享给大家。
2.先说一下题目的位置:牛客网https://www.nowcoder.com/activity/oj→在线编程→JS能力测评经典题
3.数组部分共14题,大部分有两种解法,一种用常规循环做,一种用Array对象的方法做。
<!DOCTYPE HTML> <html> <head> <title>index</title> <meta charset="utf-8"> <meta name="Author" content="Helen"> <script> //共14题 //case1:找出元素 item 在给定数组 arr 中的位置,如果数组中存在 item,则返回元素在数组中的位置,否则返回 -1 // 解法一:通过自定义函数来解 function indexOf(arr, item) { for(var i=0;i<arr.length;i++){ if(arr[i]===item){ return i; } }//end for return -1; } //解法二:直接通过函数方法来解 function indexOf(arr, item) { return arr.indexOf(item); } //case02:计算给定数组 arr 中所有元素的总和,数组中的元素均为 Number 类型 //方法一:用for循环常规方法做 function sum(arr) { var sum=0; for(var i=0;i<arr.length;i++){ sum+=arr[i]; } return sum; } //方法二:用Array.reduce()方法做 function sum(arr) { return arr.reduce(function(prev,cur){ return prev+cur; }); } //case03:移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组 //方法一:用for循环常规方法做,判断不等于item的值,将他赋给新的数组 function remove(arr, item) { var newArr=[]; for(var i=0;i<arr.length;i++){ if(arr[i]!==item){ newArr[newArr.length]=arr[i]; } } return newArr; } //方法二:用arr.filter方法做,将满足判定条件的元素返回成新的数组 function remove(arr, item) { var newArr=arr.filter(function(ele){ return ele!==item; }); return newArr; } // case04 移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回 //用indexOf和splice这两个方法来解 function removeWithoutCopy(arr, item) { while(arr.indexOf(item)!==-1){ //判断数组中有没有item这个元素 var index=arr.indexOf(item); //有的话就通过下标删掉这个元素 arr.splice(index,1); } return arr; } //case05: 在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组 //写法一:用for循环,先将arr的元素给newArr,注意如果直接数组赋值,newArr也是指向arr的内存,新增元素会修改arr function append(arr, item) { var newArr=[]; for(var i=0;i<arr.length;i++){ newArr[newArr.length]=arr[i]; } newArr[newArr.length]=item; return newArr; } //写法二:用slice和push方法写,思路还和上面一样 function append(arr, item) { var newArr=arr.slice(0,arr.length); newArr.push(item); return newArr; } //case06:删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组 // 两个写法和上个例子思路一样 //写法一:用for循环 function truncate(arr) { var newArr=[]; for(var i=0;i<arr.length;i++){ newArr[newArr.length]=arr[i]; } newArr.length=newArr.length-1; return newArr; } //写法二:用slice和pop方法写 function truncate(arr) { var newArr=arr.slice(0,arr.length); newArr.pop(); return newArr; } //case07:在数组 arr 开头添加元素 item。不要直接修改数组 arr,结果返回新的数组 //方法一:先给第一个元素赋值item,其他用for赋值 function prepend(arr, item) { var newArr=[item]; for(var i=0;i<arr.length;i++){ newArr[newArr.length]=arr[i]; } return newArr; } //方法二 function prepend(arr, item) { var newArr=[item]; for(var i=0;i<arr.length;i++){ newArr.push(arr[i]); } return newArr; } //case08 删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组 //方法一:直接把arr的第二个元素开始赋值给新数组 function curtail(arr) { var newArr=[]; for(var i=1;i<arr.length;i++){ newArr[newArr.length]=arr[i]; } return newArr; } //用slice实现最简单,原理同上 function curtail(arr) { var newArr=arr.slice(1,arr.length); return newArr; } // case09:合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组 //两个for循环,分别给newArr数组赋值 function concat(arr1, arr2) { var newArr=[]; for(var i=0;i<arr1.length;i++){ newArr[newArr.length]=arr1[i]; } for(var j=0;j<arr2.length;j++){ newArr[newArr.length]=arr2[j]; } return newArr; } //方法二:concat直接使用 function concat(arr1, arr2) { var newArr=arr1.concat(arr2); return newArr; } //case10:在数组 arr 的 index 处添加元素 item。不要直接修改数组 arr,结果返回新的数组 // 方法一 function insert(arr, item, index) { var newArr=[]; for(var i=0;i<index;i++){ newArr[newArr.length]=arr[i]; } newArr[index]=item; for(var j=index;j<arr.length;j++){ newArr[newArr.length]=arr[j]; } return newArr; } //方法二 function insert(arr, item, index) { var newArr=arr.slice(0,arr.length); newArr.splice(index,0,item); return newArr; } //case11:统计数组 arr 中值等于 item 的元素出现的次数 function count(arr, item) { var newArr=arr.filter(function (ele){ return ele===item; }); return newArr.length; } // case12:找出数组 arr 中重复出现过的元素 // 方法一:比较麻烦的一个方法 function duplicates(arr) { var newArr=[]; var newArr2=[]; for(var i=0;i<arr.length;i++){ if(newArr.indexOf(arr[i])===-1){ //判断arr中的元素是否存在于newArr中 newArr.push(arr[i]); //若不存在,则把这个元素加入newArr, } else if(newArr2.indexOf(arr[i])===-1){ //如果这个元素存在于newArr中,那么继续判断它是否存在于newArr2 newArr2.push(arr[i]); //如果不存在,则把这个元素加入newArr2, } } return newArr2; } //方法二:用indexOf和lastIndexOf判断是否存在相同元素,并判断这个元素是否存在于newArr中 function duplicates(arr) { var newArr = []; arr.forEach(function (ele) { if (arr.indexOf(ele) !== arr.lastIndexOf(ele) && newArr.indexOf(ele) === -1) { newArr.push(ele); } }); return newArr; } //case13:为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组 function square(arr) { var newArr=arr.map(ele => ele*ele); return newArr; } //case14:在数组 arr 中,查找值与 item 相等的元素出现的所有位置(题目有误,应该是和target相等的元素) //方法一: function findAllOccurrences(arr, target) { var newArr=[]; for(var i=0;i<arr.length;i++){ if(arr[i]===target){ newArr[newArr.length]=i; } } return newArr; } //方法二:私教给的一种写法 function findAllOccurrences(arr, target) { var newArr=[],index=arr.lastIndexOf(target); //这里必须倒序查找,倒序找到一个删除一个,再继续找,这样下标才不会变 while(index>-1){ newArr.push(index); arr.splice(index,1); index=arr.lastIndexOf(target) } return newArr; } //方法三--也算一种写法 function findAllOccurrences(arr, target) { var newArr=[]; arr.filter(function (ele,index) { if(ele===target){ newArr.push(index); } return newArr; }); return newArr; } </script> </head> <body> </body> </html>
数组后面的案例
<!DOCTYPE HTML> <html> <head> <title>index</title> <meta charset="utf-8"> <meta name="Author" content="Helen"> <style> * { margin: 0; padding: 0; } </style> </head> <body> <script> //case 15:给定的 js 代码中存在全局变量,请修复 //加一个var 让隐式全局变量变为局部变量 function globals() { var myObject = { name : 'Jory' }; return myObject; } //方法二 function globals() { return {name : 'Jory'}; } //case 16 //原题:请修复给定的 js 代码中,函数定义存在的问题,要求输入true,得到a //问题点:函数声明如果放到if else语句中,在IE8中会出问题,因为预解析的导致的,所以可以用函数表达式代替 function functions(flag) { if (flag) { function getValue() { return 'a'; } } else { function getValue() { return 'b'; } } return getValue(); } //解决:方法一 function functions(flag) { function getValue(){ if(flag){ return "a"; }else { return "b"; } } return getValue(); } //方法二: function functions(flag) { var ff; if(true){ ff=function (){ return "a"; } }else { ff=function (){ return "b"; } } return ff(); } //case17 :修改 js 代码中 parseInt 的调用方式,使之通过全部测试用例 //异常原因:parseInt(str,进制) 共接收两个参数,其中第一个是一个字符串,第二个参数是进制基数,不写第二个参数默认是十进制,但是如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数 //解法一: function parse2Int(num) { return parseInt(parseFloat(num)); } //解法二:加上进制 function parse2Int(num) { return parseInt(num,10); } //case 18:判断 val1 和 val2 是否完全等同 function identity(val1, val2) { if(val1===val2){ return true; }else { return false; } } // 三元表达式写法: function identity(val1, val2) { return val1===val2 ; } // case 19:实现一个打点计时器,要求 // 1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1 // 2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作 // 3、第一个数需要立即输出 function count(start, end) { var num=start; console.log(num); var timeId=setInterval(function(){ num++; console.log(num); if(num===end){ clearInterval(timeId); } },100); return { cancel: function(){ clearInterval(timeId); } } } // case20:流程控制:实现 fizzBuzz 函数,参数 num 与返回值的关系如下: // 1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz // 2、如果 num 能被 3 整除,返回字符串 fizz // 3、如果 num 能被 5 整除,返回字符串 buzz // 4、如果参数为空或者不是 Number 类型,返回 false // 5、其余情况,返回参数 num // 解法一: function fizzBuzz(num) { if(num%3===0 && num%5===0){ return "fizzbuzz"; } if(num%3===0){ return "fizz"; } if(num%5===0){ return "buzz"; } if(num===null||isNaN(Number(num))){ return false; } return num; } //解法二: function fizzBuzz(num) { if(num%3===0 && num%5===0){ return "fizzbuzz"; }else if(num%3===0){ return "fizz"; }else if(num%5===0){ return "buzz"; } else if(num===null||typeof num !="number" ){ return false; }else { return num; } } //case 21将数组 arr 中的元素作为调用函数 fn 的参数 function argsAsArray(fn, arr) { return fn.apply(null,arr); } //case 22:将函数 fn 的执行上下文改为 obj 对象 function speak(fn, obj) { return fn.call(obj); } //解法二: function speak(fn, obj) { return fn.apply(obj); } //解法三: function speak(fn, obj) { return fn.bind(obj)(); //用bind自调用 } // case 23:实现函数 functionFunction,调用之后满足如下条件: // 1、返回值为一个函数 f // 2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', ' // 3、所有函数的参数数量为 1,且均为 String 类型 function functionFunction(str) { return function(s){ return str+", "+s; } } // 解法二: function functionFunction(str) { return function(){ return str+", "+arguments[0]; } } // case24:实现函数 makeClosures,调用之后满足如下条件: // 1、返回一个函数数组 result,长度与 arr 相同 // 2、运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同 // 错误写法:因为调用的时候result[i]()这里不传参,所以fn(arr[i])是个已经计算好的值,而第一种写法函数没被调用,所以未执行fn(arr[i]),所以fn(arr[i]) // 以最后一个i的值,也就是arr.length计算 //result[i]指向的是同一个函数的地址,而第二种写法是每个result[i]对应一个函数 function makeClosures(arr, fn) { var result=[]; for(var i=0;i<arr.length;i++){ result[i]=function (i){ return fn(arr[i]); } } return result; } // 解法 function makeClosures(arr, fn) { var result=[]; for(var i=0;i<arr.length;i++){ result[i]=f1(i); } function f1(i){ return function (){ return fn(arr[i]); } } return result; } // case25:已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件: // 1、返回一个函数 result,该函数接受一个参数 // 2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致 // 解法一: function partial(fn, str1, str2) { return function result(str3){ return fn( str1, str2, str3) } } //解法二: function partial(fn, str1, str2) { return function result(str3){ return fn.call(this, str1, str2, str3) } } //解法三: function partial(fn, str1, str2) { return function result(str3){ return fn.apply(this, [str1, str2, str3]) } } //解法四: function partial(fn, str1, str2) { return function result(str3){ return fn.bind(this, str1, str2)(str3) } } // case26:函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。 // 解法一: function useArguments() { var sum=0; for(var i=0;i<arguments.length;i++){ sum+=arguments[i]; } return sum; } //解法二:将arguments伪数组转换为真数组,然后调用数组的reduce方法 function useArguments() { var sum=0; return Array.prototype.slice.call(arguments).reduce(function(prev,cur){ return prev+cur; },0) } // case27:实现函数 callIt,调用之后满足如下条件 // 1、返回的结果为调用 fn 之后的结果 // 2、fn 的调用参数为 callIt 的第一个参数之后的全部参数 // 解法一:注意apply,call和bind的使用 function callIt(fn) { var arr=Array.prototype.slice.call(arguments); arr.shift(); return fn.apply(null,arr); } //解法二:最简单的解法,用slice直接取其后面的参数组成新数组 function callIt(fn) { var arr=Array.prototype.slice.call(arguments,1); return fn.apply(null,arr); } // case28:实现函数 partialUsingArguments,调用之后满足如下条件: // 1、返回一个函数 result // 2、调用 result 之后,返回的结果与调用函数 fn 的结果一致 // 3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数 // 解法:重点在于获得两个函数的arguments参数并转换为数组,然后用concat方法拼接 function partialUsingArguments(fn) { var arr=Array.prototype.slice.call(arguments,1); var result= function result(){ var arr2=Array.prototype.slice.call(arguments); return fn.apply(this, arr.concat(arr2)); } return result; } // case29:已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件: // 1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数) // 2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1 // 3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1 // 4、调用 c 之后,返回的结果与调用 fn 的返回值一致 // 5、fn 的参数依次为函数 a, b, c 的调用参数 // 解法一:本题考查函数柯里化,但还没学,先手动写个闭包解法 function curryIt(fn) { return function (a){ return function(b){ return function(c){ return fn.call(null,a,b,c); } } } } //case30:返回参数 a 和 b 的逻辑或运算结果 function or(a, b) { return a||b; } //case31:返回参数 a 和 b 的逻辑且运算结果 function and(a, b) { return a&&b; } // case 32:完成函数 createModule,调用之后满足如下要求: // 1、返回一个对象 // 2、对象的 greeting 属性值等于 str1, name 属性值等于 str2 // 3、对象存在一个 sayIt 方法,该方法返回的字符串为 greeting属性值 + ', ' + name属性值 function createModule(str1, str2) { return { greeting :str1, name :str2, sayIt :function(){ return this.greeting + ', ' +this.name; } } } // case33:获取数字 num 二进制形式第 bit 位的值。注意: // 1、bit 从 1 开始 // 2、返回 0 或 1 // 3、举例:2 的二进制为 10,第 1 位为 0,第 2 位为 1 // 注意要写二进制形式 function valueAtBit(num, bit) { var str=num.toString(2); var result=str[str.length-bit]; return Number(result); } //case34:给定二进制字符串,将其换算成对应的十进制数字 function base10(str) { return parseInt(str,2); } //case35:将给定数字转换成二进制字符串。如果字符串长度不足 8 位,则在前面补 0 到满8位。 function convertToBinary(num) { var str=num.toString(2); while(str.length<8){ str=0+str; } return str; } //解法二:新的思路 function convertToBinary(num) { var str=num.toString(2); var l=str.length; if(l<8){ var zero="0000000"; str=zero.substr(0,8-l)+str; } return str; } // case36:求 a 和 b 相乘的值,a 和 b 可能是小数,需要注意结果的精度问题 function multiply(a, b) { var stra=a.toString(); var strb=b.toString(); var len1=stra.indexOf(".")===-1 ? 0 : (stra.length-stra.indexOf(".")-1) ; var len2=strb.indexOf(".")===-1 ? 0 : (strb.length-strb.indexOf(".")-1) ; return (a*b).toFixed(len1+len2); } //case37: 将函数 fn 的执行上下文改为 obj,返回 fn 执行后的值 //解法一: function alterContext(fn, obj) { return fn.call(obj); } //解法二: function alterContext(fn, obj) { return fn.apply(obj); } //解法三: function alterContext(fn, obj) { return fn.bind(obj)(); } //case38:给定一个构造函数 constructor,请完成 alterObjects 方法,将 constructor 的所有实例的 greeting 属性指向给定的 greeting 变量。 function alterObjects(constructor, greeting) { constructor.prototype.greeting=greeting; } //case39:找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~) // 1、返回数组,格式为 key: value // 2、结果数组不要求顺序 //考察方法hasOwnProperty的使用 function iterate(obj) { var arr=[]; for(var key in obj){ if(obj.hasOwnProperty(key)){ arr.push(key+": "+obj[key]) } } return arr; } //case40:给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false function containsNumber(str) { var reg=/d+/; return reg.test(str); } //case41:给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false // 1表示重复正则第一个圆括号内匹配到的内容; 2表示重复正则第二个圆括号内匹配到的内容 function containsRepeatingLetter(str) { var reg=/([a-zA-Z])1/; return reg.test(str); } //casse 42:给定字符串 str,检查其是否以元音字母结尾 // 1、元音字母包括 a,e,i,o,u,以及对应的大写 // 2、包含返回 true,否则返回 false function endsWithVowel(str) { var arr=["a","e","i","o","u","A","E","I","O","U"]; var flag=false; for(var i=0;i<arr.length;i++){ if(str.lastIndexOf(arr[i])===str.length-1){ flag=true; } } return flag; } //case 43:给定字符串 str,检查其是否包含 连续3个数字 // 1、如果包含,返回最新出现的 3 个数字的字符串 // 2、如果不包含,返回 false function captureThreeNumbers(str) { var reg=/d{3}/; if(reg.test(str)){ return str.match(reg)[0]; } else{ return false; } } //case 44:给定字符串 str,检查其是否符合如下格式 // 1、XXX-XXX-XXXX // 2、其中 X 为 Number 类型 function matchesPattern(str) { var reg=/^d{3}[-]d{3}[-]d{4}$/; return reg.test(str); } //case 45:给定字符串 str,检查其是否符合美元书写格式 // 1、以 $ 开始 // 2、整数部分,从个位起,满 3 个数字用 , 分隔 // 3、如果为小数,则小数部分长度为 2 // 4、正确的格式如:$1,023,032.03 或者 $2.03,错误的格式如:$3,432,12.12 或者 $34,344.3 function isUSD(str) { var reg=/^[$][1-9]d{0,2}([,]d{3})*([.]d{2})?$/; return reg.test(str); } </script> </body> </html>