• 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>
    

      

  • 相关阅读:
    JavaScript 深入之从原型到原型链
    js重写内置的call、apply、bind
    js中flat方法的实现原理
    【我的物联网成长记6】由浅入深了解NB-IoT【华为云技术分享】
    GO富集分析示例【华为云技术分享】
    华为“方舟编译器”到底是啥?一文看懂TA如何让手机性能再突破【华为云技术分享】
    无码系列-7-代码的语文修养_上篇【华为云技术分享】
    机器学习笔记(一)----基本概念【华为云技术分享】
    性能达到原生 MySQL 七倍,华为云 Taurus 技术解读【华为云技术分享】
    【立即报名】人脸情绪识别案例分享【华为云技术分享】
  • 原文地址:https://www.cnblogs.com/Helen-code/p/11438006.html
Copyright © 2020-2023  润新知