JS-03 牛客网练习

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>

  

原文地址:https://www.cnblogs.com/Helen-code/p/11438006.html