【整理】牛客网编程题-前端篇(入门难度)

(1)dom节点查找

题目描述:
查找两个节点的最近的一个共同父节点,可以包括节点自身
输入描述:oNode1 和 oNode2 在同一文档中,且不会为相同的节点
解题思路:
判断一个节点以及它的父节点是否包含另一个节点。

function commonParentNode(oNode1, oNode2) {
    while(true){
        oNode1 = oNode1.parentNode;
        if(oNode1.contains(oNode2)){
            return oNode1;
        }
    }
}

两边找:

function commonParentNode(oNode1, oNode2) {
    let parentNode1 = oNode1.parentNode;
    let parentNode2 = oNode2.parentNode;
    while(true){
        if(parentNode1.contains(oNode2)){
            return parentNode1;
        }
        if(parentNode2.contains(oNode1)){
            return parentNode2;
        }
        parentNode1 = parentNode1.parentNode;
        parentNode2 = parentNode2.parentNode;
    }
}

let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。
与var不同的是,它声明的变量只能是全局或者整个函数块的。换句话,块级 == { }

(2)根据包名,在指定空间中创建对象

题目描述:
根据包名,在指定空间中创建对象
输入描述:namespace({a: {test: 1, b: 2}}, ‘a.b.c.d’)
输出描述:{a: {test: 1, b: {c: {d: {}}}}}
解题思路:

function namespace(oNamespace, sPackage) {    
    oNamespace = oNamespace || {};
    let tmp = oNamespace;
    let pkgs = sPackage.split('.');
    for (let i = 0; i < pkgs.length; i++) {
        tmp[pkgs[i]] = tmp[pkgs[i]] || {};
        tmp = tmp[pkgs[i]];
    }
    return oNamespace;
}

(3)斐波那契数列

题目描述:
用 JavaScript 实现斐波那契数列函数,返回第n个斐波那契数。 f(1) = 1, f(2) = 1 等
解题思路:

function fibonacci(n) {
    if (n==1||n==2) {
        return 1;
    }
    return fibonacci(n-1) + fibonacci(n-2);
}

(4)字符串字符统计

题目描述:
统计字符串中每个字符的出现频率,返回一个 Object,key 为统计字符,value 为出现频率

  1. 不限制 key 的顺序
  2. 输入的字符串参数不会为空
  3. 忽略空白字符
    示例1
    输入:‘hello world’
    输出:{h: 1, e: 1, l: 3, o: 2, w: 1, r: 1, d: 1}
    解题思路:
function count(str) {
	var obj={};
    str=str.replace(/\s/,'');
    for(var i=0;i<str.length;i++){
        if(obj.hasOwnProperty(str[i])){
            obj[str[i]]++;
        }else{
            obj[str[i]]=1;
        }
    }
    return obj;
}

hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性。

(5)数组求和

题目描述:
计算给定数组 arr 中所有元素的总和
输入描述:数组中的元素均为 Number 类型
示例1
输入:[ 1, 2, 3, 4 ]
输出:10
解题思路:

function sum(arr) {
    var sum = 0;
    for (var i=0;i<arr.length;i++) {
        sum += arr[i];
    }
    return sum;
}

(6)删除数组最后一个元素

题目描述:
删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组
示例1
输入:[1, 2, 3, 4]
输出:[1, 2, 3]
解题思路:

function truncate(arr) {
    var newArray = arr.slice(0,arr.length-1);
    return newArray;
}

slice() 方法可从已有的数组中返回选定的元素。语法:arrayObject.slice(start,end)
从 start 开始(包括 start)到 end 结束(不包括 end)为止的所有字符。
还可以使用push,将原数组除最后一个元素添加到新数组:

function truncate(arr) {
    var newArray = [];
    for (var i=0;i<arr.length-1;i++) {
        newArray.push(arr[i])
    }
    return newArray;
}

push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。

(7)添加元素

题目描述:
在数组 arr 开头添加元素 item。不要直接修改数组 arr,结果返回新的数组
示例1
输入:[1, 2, 3, 4], 10
输出:[10, 1, 2, 3, 4]
解题思路:

function prepend(arr, item) {
    var newArray = arr.slice(0);
    newArray.unshift(item);
    return newArray;
}

(8)删除数组第一个元素

题目描述:
删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组
示例1
输入:[1, 2, 3, 4]
输出:[2, 3, 4]
解题思路:
这是整理的某篇文章,现在找不到原文链接了,把内容贴在这里,如果有问题联系我删。
第一种:运用slice()的浅克隆去复制元素从第二个开始到最后一个

function curtail(arr) {
    let newArray = arr.slice(1);
    return newArray;
}

第二种:splice()的删除功能

function curtail(arr) {
    var m = arr.slice(0);
    m.splice(0,1);
    return m;
}

第三种:filter过滤下标,返回满足不等0的下标的元素

function curtail(arr) {
    return arr.filter(function(ele,idx,arr){
        return idx !== 0;
    });
}

第四种:shift()删除原数组的首个元素

function curtail(arr) {
    var m = arr.slice(0);
    m.shift();
    return m;
}

第五种:join字符串连接后运用split进行分离为新数组

function curtail(arr) {
    var m = arr.join().split(',');
    m.shift();
    return m;
}

第六种:apply数组参数化后放入m数组

function curtail(arr) {
    var m = [];
    [].push.apply(m,arr);
    m.shift();
    return m;
}

第七种:concat数组链接出新数组。

function curtail(arr) {
    var m = arr.concat();
    m.shift();
    return m;
}

(9)数组合并

题目描述:
合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组
示例1
输入:[1, 2, 3, 4], [‘a’, ‘b’, ‘c’, 1]
输出:[1, 2, 3, 4, ‘a’, ‘b’, ‘c’, 1]
解题思路:

function concat(arr1, arr2) {
    return arr1.concat(arr2);
}

(10)计数

题目描述:
统计数组 arr 中值等于 item 的元素出现的次数
示例1
输入:[1, 2, 4, 4, 3, 4, 3], 4
输出:3
解题思路:

function count(arr, item) {
    var count = 0;
    for (var i=0;i<arr.length;i++) {
        if (arr[i]===item) {
            count++;
        }
    }
    return count;
}

(11)求二次方

题目描述:
为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组
示例1
输入:[1, 2, 3, 4]
输出:[1, 4, 9, 16]
解题思路:

function square(arr) {
    var newArray = [];
    for (i in arr) {
        newArray.push(arr[i]*arr[i])
    }
    return newArray;
}

使用Array map() 方法:

function square(arr) {     
   return arr.map(index=>Math.pow(index,2))
}

map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
pow() 方法可返回 x 的 y 次幂的值。

(12)查找元素位置

题目描述:
在数组 arr 中,查找值与 item 相等的元素出现的所有位置
示例1
输入:[‘a’,‘b’,‘c’,‘d’,‘e’,‘f’,‘a’,‘b’,‘c’] ‘a’
输出:[0, 6]
解题思路:

function findAllOccurrences(arr, target) {
    var list = [];
    arr.forEach(function(value,index,array){
        (value == target) ? list.push(index) : 0
    })
    return list;
}

(13)避免全局变量

题目描述:
给定的 js 代码中存在全局变量,请修复

function globals() {
    myObject = {
      name : 'Jory'
    };

    return myObject;
}

解题思路:
加上 let 或者 var

function globals() {
    let myObject = {
        name : 'Jory'
    };

    return myObject;
}

(14)正确使用parseInt

题目描述:
修改 js 代码中 parseInt 的调用方式,使之通过全部测试用例
示例1
输入:‘12’
输出:12
示例2
输入:‘12px’
输出:12
示例3
输入:‘0x12’
输出:0
解题思路:

function parse2Int(num) {
    return parseInt(num,10);
}

parseInt() 函数可解析一个字符串,并返回一个整数。
当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
当忽略参数 radix , JavaScript 默认数字的基数如下:
如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。
如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。
如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
radix:可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

(15)完全等同

题目描述:
判断 val1 和 val2 是否完全等同
解题思路:

function identity(val1, val2) {
    return val1 === val2;
}

(16)函数传参

题目描述:
将数组 arr 中的元素作为调用函数 fn 的参数
示例1
输入:function (greeting, name, punctuation) {return greeting + ', ’ + name + (punctuation || ‘!’);}, [‘Hello’, ‘Ellie’, ‘!’]
输出:Hello, Ellie!
解题思路:

function argsAsArray(fn, arr) {
    return fn.apply(this, arr);
}

call,apply都属于Function.prototype的一个方法,作用是传入参数调用函数。
不同点:方法传入的参数不同。
function.call (this, arg1, arg2); function.apply (this, args);

(17)函数的上下文

题目描述:
将函数 fn 的执行上下文改为 obj 对象
示例1
输入:function () {return this.greeting + ', ’ + this.name + ‘!!!’;}, {greeting: ‘Hello’, name: ‘Rebecca’}
输出:Hello, Rebecca!!!
解题思路:

function speak(fn, obj) {
    return fn.call(obj);
}

函数上下文:this参数
函数用圆括号调用,函数的上下文是window对象
函数如果作为一个对象的方法,对象打点调用,函数的上下文就是这个对象
函数是事件处理函数,函数的上下文就是触发这个事件的对象
定时器调用函数,上下文是window对象
数组中存放的函数,被数组索引之后加圆括号调用,this就是这个数组

(18)二次封装函数

题目描述:
已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
1、返回一个函数 result,该函数接受一个参数
2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
示例1
输入:var sayIt = function(greeting, name, punctuation) { return greeting + ‘, ’ + name + (punctuation || ‘!’); }; partial(sayIt, ‘Hello’, ‘Ellie’)(’!!!’);
输出:Hello, Ellie!!!
解题思路:

function partial(fn, str1, str2) {
    var f = function(str3) {
        return fn(str1, str2, str3);
    }
    return f;
}

(19)使用arguments

题目描述:
函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。
示例1
输入:1, 2, 3, 4
输出:10
解题思路:

function useArguments() {
    var sum = 0;
    for (var i=0;i<arguments.length;i++) {
        sum += arguments[i];
    }
    return sum;
}

(20)柯里化

题目描述:
已知 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 的调用参数
示例1
输入:var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3);
输出:6
解题思路:

function curryIt(fn) {
    return function a(arg1) {
        return function b(arg2) {
            return function c(arg3) {
                return fn.call(this, arg1, arg2, arg3);
            }
        }
    }
}

函数柯里化(currying)又称部分求值。一个 currying 的函数首先会接受一些参数,接受了这些参数之后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。

(21)或运算

题目描述:
返回参数 a 和 b 的逻辑或运算结果
示例1
输入:false, true
输出:true
解题思路:

function or(a, b) {
    return a || b;
}

(22)且运算

题目描述:
返回参数 a 和 b 的逻辑且运算结果
示例1
输入:false, true
输出:false
解题思路:

function and(a, b) {
    return a && b;
}

(23)二进制转换

题目描述:
给定二进制字符串,将其换算成对应的十进制数字
示例1
输入:‘11000000’
输出:192
解题思路:

function base10(str) {
    return parseInt(str, 2);
}

(24)乘法

题目描述:
求 a 和 b 相乘的值,a 和 b 可能是小数,需要注意结果的精度问题
示例1
输入:3, 0.0001
输出:0.0003
解题思路:

function multiply(a, b) {
    a = '' + a;
    b = b.toString();
    var alen = (a.indexOf('.')==-1)?1:Math.pow(10, a.length - 2);
    var blen = (b.indexOf('.')==-1)?1:Math.pow(10, b.length - 2);
    return (a * alen) * (b * blen) / alen / blen;
}

(25)改变上下文

题目描述:
将函数 fn 的执行上下文改为 obj,返回 fn 执行后的值
示例1
输入:alterContext(function() {return this.greeting + ', ’ + this.name + ‘!’; }, {name: ‘Rebecca’, greeting: ‘Yo’ })
输出:Yo, Rebecca!
解题思路:

function alterContext(fn, obj) {
    return fn.call(obj);
}

(26)批量改变对象的属性

题目描述:
给定一个构造函数 constructor,请完成 alterObjects 方法,将 constructor 的所有实例的 greeting 属性指向给定的 greeting 变量。
示例1
输入:
var C = function(name) {this.name = name; return this;};
var obj1 = new C(‘Rebecca’);
alterObjects(C, ‘What’s up’); obj1.greeting;
输出:What’s up
解题思路:

function alterObjects(constructor, greeting) {
	return constructor.prototype.greeting = greeting;
}

prototype 属性可以用来向对象添加属性和方法。

(27)判断是否包含数字

题目描述:
给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false
示例1
输入:‘abc123’
输出:true
解题思路:

function containsNumber(str) {
    var reg = /\d/;
    return reg.test(str);
}

(28)判断是否以元音字母结尾

题目描述:
给定字符串 str,检查其是否以元音字母结尾
1、元音字母包括 a,e,i,o,u,以及对应的大写
2、包含返回 true,否则返回 false
示例1
输入:‘gorilla’
输出:true
解题思路:

function endsWithVowel(str) {
    var reg = /[aeiou]$/i;
    return reg.test(str);
}

正则表达式中/i,/g,/ig,/gi,/m的区别和含义:

  • /i (忽略大小写)
  • /g (全文查找出现的所有匹配字符)
  • /m (多行查找)
  • /gi(全文查找、忽略大小写)
  • /ig(全文查找、忽略大小写)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值