【整理】牛客网编程题前端篇(中等难度)

(1)时间格式化输出

题目描述:
按所给的时间格式输出指定的时间
格式说明
对于 2014.09.05 13:14:20
yyyy: 年份,2014
yy: 年份,14
MM: 月份,补满两位,09
M: 月份, 9
dd: 日期,补满两位,05
d: 日期, 5
HH: 24制小时,补满两位,13
H: 24制小时,13
hh: 12制小时,补满两位,01
h: 12制小时,1
mm: 分钟,补满两位,14
m: 分钟,14
ss: 秒,补满两位,20
s: 秒,20
w: 星期,为 [‘日’, ‘一’, ‘二’, ‘三’, ‘四’, ‘五’, ‘六’] 中的某一个,本 demo 结果为五
示例1
输入:formatDate(new Date(1409894060000), ‘yyyy-MM-dd HH:mm:ss 星期w’)
输出:2014-09-05 13:14:20 星期五
解题思路:

function formatDate(date, format) {
    const week = {
        "0" : "\u65e5",  //日
        "1" : "\u4e00",  //一
        "2" : "\u4e8c",  //二
        "3" : "\u4e09",  //三
        "4" : "\u56db",  //四
        "5" : "\u4e94",  //五
        "6" : "\u516d"。 //六
    }, fmt = {
        "y+" : date.getFullYear(),     //年份
        "M+" : date.getMonth()+1,      //月份
        "d+" : date.getDate(),         //日
        "H+" : date.getHours(),        //小时
        "h+" : date.getHours()%12||12, //小时
        "m+" : date.getMinutes(),      //分
        "s+" : date.getSeconds(),      //秒
        "S"  : date.getMilliseconds(), //毫秒
        "w"  : week[date.getDay()+""]  //周,转换为字符串型
    };

    for(let k in fmt){           
        if(new RegExp("("+k+")").test(format)){
            format = format.replace(
            RegExp.$1,
            RegExp.$1.length===1?fmt[k]:("00"+ fmt[k]).substr(-RegExp.$1.length)
            );
        }
    }
    return format; 
}

RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。
RegExp().test() 用于匹配表达式,存在则返回true
RegExp.$1是RegExp的一个属性,指的是与正则表达式匹配的第一个子匹配(以括号为标志)字符串
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符。
正则表达式语法:
特殊字符:所谓特殊字符,就是一些有特殊含义的字符

特别字符描述
$匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 $。
()标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。
*匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
.匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。
[标记一个中括号表达式的开始。要匹配 [,请使用 [。
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\’ 匹配 “”,而 ‘(’ 则匹配 “(”。
^匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。
{标记限定符表达式的开始。要匹配 {,请使用 {。
|指明两项之间的一个选择。要匹配 |,请使用\ |。

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。

符号描述
*匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
+匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
?匹配前面的子表达式零次或一次。例如,“do(es)?” 可以匹配 “do” 、 “does” 中的 “does” 、 “doxy” 中的 “do” 。? 等价于 {0,1}。
{n}n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o
{n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。

(2)邮箱字符串判断

题目描述:
判断输入是否是正确的邮箱格式
输入描述:邮箱字符串
输出描述:true表示格式正确
解题思路:

function isAvailableEmail(sEmail) {
    var regexp = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    return regexp.test(sEmail)
}

(3)修改this指向

描述:
封装函数 f,使 f 的 this 指向指定的对象
示例1
输入:无
输出:无
解题思路:

function bindThis(f, oTarget) {
    return f.bind(oTarget);
}

bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()第一个参数的值。

(4)颜色字符串转换

题目描述:
将 rgb 颜色字符串转换为十六进制的形式,如 rgb(255, 255, 255) 转为 #ffffff

  1. rgb 中每个 , 后面的空格数量不固定
  2. 十六进制表达式使用六位小写字母
  3. 如果输入不符合 rgb 格式,返回原始输入
    示例1
    输入:‘rgb(255, 255, 255)’
    输出:#ffffff
    解题思路:
function rgb2hex(sRGB) {
    let reg = /^(rgb|RGB)\((\d+),\s*(\d+),\s*(\d+)\)$/;
    if (!reg.test(sRGB)) {
        return sRGB;
    }
    let temp = sRGB.replace(reg,'$2,$3,$4');
    return '#'+temp.split(',').map(item=>{
        if(+item>16) {
            return (+item).toString(16);
        } else {
            return '0'+(+item).toString(16);
        }
    }).join('');
}

replace方法主要用于将字符串中符合匹配条件的字串替换成其他的字符串,返回替换后的字符串,且原字符串不变。
+value可以理解为Number(value),转换为数字型。
上面这种解法似乎没有考虑到数值超过255的情况:

function rgb2hex(sRGB) {
    let reg = /^(rgb|RGB)\((\d+),\s*(\d+),\s*(\d+)\)$/;
    var ret = sRGB.match(reg);
    if (!ret) {
        return sRGB;
    } else {
        var str = '#';
        for (var i=2;i<=4;i++) {
            var m = parseInt(ret[i]);
            if (m<=255 && m>=0) {
                str += (m<16?'0'+m.toString(16):m.toString(16));
            } else {
                return sRGB;
            }
        }
        return str;
    }
}

exec() 是RegExp对象的方法,而 match() 是String对象的方法。
都会返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回null。
返回的数组虽然是Array 的实例,但包含两个额外的属性:index 和 input。其中,index 表示匹配项在字符串中的位置,而 input 表示应用正则表达式的字符串。
在数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含一项)。

(5)将字符串转换为驼峰格式

描述:
css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能

  1. 以 - 为分隔符,将第二个起的非空单词首字母转为大写
  2. -webkit-border-image 转换后的结果为 webkitBorderImage
    示例1
    输入:‘font-size’
    输出:fontSize
    解题思路:
function cssStyle2DomStyle(sName) {
    let arr = sName.split('-');
    if(!arr[0]) {
        arr.shift();
    }
    for(let i = 1; i < arr.length; i++){
        let word = arr[i];
        arr[i] = word.replace(word[0], word[0].toUpperCase());
    }
    return arr.join('');
}

shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。

(6)加粗文字

描述:
使用一个标签将“牛客网”三个字加粗显示

const ele = document.querySelector('p');
ele.innerHTML = ele.innerHTML.replace(/牛客网/g, '<strong>牛客网</strong>')

(7)移除数组中的元素

描述:

移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回
示例1
输入:[1, 2, 2, 3, 4, 2, 2], 2
输出:[1, 3, 4]
解题思路:

function removeWithoutCopy(arr, item) {
    for (let i=0;i<arr.length;i++) {
        if (arr[i]==item) {
            arr.splice(i,1);
            i--;
        }
    }
    return arr;
}

注意:删除元素后需要将索引值减去1,否则会跳过一个元素。

(8)查找重复元素

描述:
找出数组 arr 中重复出现过的元素(不用考虑返回顺序)
示例1
输入:[1, 2, 4, 4, 3, 3, 1, 5, 3]
输出:[1, 3, 4]
解题思路:
统计每个元素出现的次数(功能多余了)

function duplicates(arr) {
    var obj = {};
    for (var i=0;i<arr.length;i++) {
        if (obj[arr[i]]) {
            obj[arr[i]]++;
        } else {
            obj[arr[i]] = 1;
        }
    }
    var arr2 = [];
    for (var key in obj) {
        if (obj[key]>1) {
            arr2.push(key);
        }
    }
    return arr2;
}

先排序,比较前后两个值是否重复:

function duplicates(arr) {
    var a=arr.sort(),b=[];
    for(var i in a){
        if(a[i]==a[i-1] && b.indexOf(a[i])==-1) b.push(a[i]); 
    }
    return b;
}

(9)计时器

描述:
实现一个打点计时器,要求
1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作
3、第一个数需要立即输出
解题思路:

function count(start, end) {
    console.log(start++);
    var timer = setInterval(function () {
        if (start<=end) {
            console.log(start++);
        } else {
            clearInterval(timer);
        }
    },100);
    return {
        cancel : function () {
            clearInterval(timer);
        }
    }
}

(10)流程控制

描述:
实现 fizzBuzz 函数,参数 num 与返回值的关系如下:
1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz
2、如果 num 能被 3 整除,返回字符串 fizz
3、如果 num 能被 5 整除,返回字符串 buzz
4、如果参数为空或者不是 Number 类型,返回 false
5、其余情况,返回参数 num
示例1
输入:15
输出:fizzbuzz
解题思路:

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;
    }
}

(11)使用闭包

描述:
实现函数 makeClosures,调用之后满足如下条件:
1、返回一个函数数组 result,长度与 arr 相同
2、运行 result 中第 i 个函数,即 resulti,结果与 fn(arr[i]) 相同
示例1
输入:
[1, 2, 3], function (x) {
return x * x;
}
输出:4
解题思路:

function makeClosures(arr, fn) {
    var result = [];
    for (var i=0;i<arr.length;i++) {
        result[i] = function () {
            return fn(arr[i]);
        }
    }
    return result;
}

(12)判断是否符合 USD 格式

描述:
给定字符串 str,检查其是否符合美元书写格式
1、以 $ 开始
2、整数部分,从个位起,满 3 个数字用 , 分隔
3、如果为小数,则小数部分长度为 2
4、正确的格式如:$1,023,032.03 或者 $2.03,错误的格式如:$3,432,12.12 或者 $34,344.3
示例1
输入:’$20,933,209.93’
输出:true
解题思路:

function isUSD(str) {
    var reg = /^\$\d{1,3}(,\d{3})*(\.\d{2})?$/;
    return reg.test(str);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值