面试之笔试(特定场景题)

1. 用js实现随机选取10-100之间的10个数字,存入一个数组,去重后求和(保证这10个数字不能出现重复)

要求:去重不能使用Set

function sumOfRandomDistinctTenNumbers(){
    // todo
    let arr = []
    let temp = {}
    let sum = 0

    function random(low, high) {
        return Math.floor(Math.random() * (high - low + 1) + low)
    }

    for (let i = 0; i < 10; i++) {
        arr.push(random(10, 100))
    }

    for(let v of arr){
        if(!temp[v]){
            temp[v] = v
            sum += v
        }
    }

    return sum;
}

2. 给定一个编码字符,按编码规则进行解码,输出字符串。编码规则是count[letter],将letter的内容count次输出,count是0或正整数,letter是区分大小写的纯字母,支持嵌套形式。

示例:

const s1 = '10[a]2[bc]'; decodeString(s); // 返回'aaaaaaaaaabcbc'
const s2 = '2[3[a]2[bc]]'; decodeString(s); // 返回 'aaabcbcaaabcbc'

解答

function decodeString(str) {
    let stack = []
    for (let i = 0; i < str.length; i++) {
        const cell = str[i]
        if (cell !== ']') {
            stack.push(cell) //进栈
        } else {
            let count = []
            let popCell = '' //循环个数
            let loopArr = []
            let loopStr = '' //结果
            while ((popCell = stack.pop()) !== '[') {
                loopArr.unshift(popCell)
            }
            // 循环输出count
            while(stack[stack.length -1] >= 0 && stack[stack.length -1] <= 9){
                count.unshift(stack.pop())
            }
            count = parseInt(count.join(''))
            for (let j = 0; j < count; j++) {
                loopStr += loopArr.join('')
            }
            stack.push(...(loopStr.split(''))) //转换结果入栈
        }
    }
    return stack.join('')
}

const s2 = '2[3[a]10[bc]]'; 
console.log(decodeString(s2))

3. 两个大数相乘

/**
 * 题目:两个大数相乘,如80位的数相乘 ,超出计算机的bit位,(64)
 * @param {*} str1 大数字符串形式
 * @param {*} str2 大数字符串形式
 * @return 相乘结果
 */

let multiply = function (str1, str2) {
    let num1 = [...str1],
        num2 = [...str2],
        numLen1 = num1.length,
        numLen2 = num2.length;
    let bitVal = []
    // 反转数字进行处理
    for (let i = numLen1 - 1; i >= 0; i--) {
        for (let j = numLen2 - 1; j >= 0; j--) {
            let ca = i + j,
                bt = i + j + 1
            // 相乘的结果 + 
            let mul = num1[i] * num2[j] + (bitVal[bt] || 0)
            bitVal[ca] = Math.floor(mul / 10) + (bitVal[ca] || 0)
            bitVal[bt] = mul % 10
        }
    }

    //去掉前置0
    let result = bitVal.join('').replace(/^0+/, '')
    //不要转成数字判断,否则可能会超精度!
    return !result ? '0' : result
}

console.log(multiply('12345678', '785857577'))

4. 组合取最小数

/**
 * 题目:输入一组数字,进行组合,输出组合中最小的数字
 * @param  {...any} numbers 一组数字,0 或者正整数
 * 数字组合,返回最小组合数
 */

function composeMini(...numbers) {
    numbers.sort(function (a, b) {
        var c1 = `${a}${b}`;
        var c2 = `${b}${a}`;
        return c1 > c2;
    });
    return numbers.join('').replace(/^0+/, '');
}
console.log(composeMini(3, 92, 16, 6, 10, 0))

5. 实现一个中间件

// 实现中间件满足如下输出
function rawMethod(a) {
    return a + 1;
}
function middleware1(next) {
    return function m1(a) {
        return next(a) + 1;
    };
}
function middleware2(next) {
    return function m2(a) {
        return next(a) + 1;
    };
}
function middleware3(next) {
    return function m3(a) {
        return next(a) + 1;
    };
}

var newMethod = applyMiddleWare(rawMethod, middleware3, middleware2);
newMethod('aaaa'); // m2 -> m3 -> rawMethod

var newMethod2 = applyMiddleWare(newMethod, middleware1);
newMethod2('aaaa'); // m1 -> m2 -> m3 -> rawMethod

解答

// 聚合函数
function applyMiddleWare(...funcs){
    const len = funcs.length
    if(len === 0){
        return arg => arg;
    }else if(len === 1){
        return funcs[0]
    }else{
        return funcs.reduce((a, b) => (...args)=> b(a)(...args))
    }
}

6. 实现一个flat [[1,2],[3]].flat() => [1,2,3]

Array.prototype.flat1 = function() {
    //递归
    let arr = this // 拿到实例
    let ret = []
    for (let item of arr) {
        if (Array.isArray(item)) {
            ret.push(...item.flat1())
        } else {
            ret.push(item)
        }
    }
    return ret
}

7. 写一个函数onlyOnce,这个函数接受另一个函数为参数,返回一个新的函数

调用新的函数也间接去调用传进去的函数,但不管你调用多少次新的函数,被传进去的函数只会被调用一次 
举例 
var newFunc = onlyOnce(alert); 
newFunc("hello"); 
newFunc("hello"); 
newFunc("hello"); 
hello只会输出一次

解答

let onlyOnce = (fn)=>{
  let isCall = false
  return (...args) =>{
    if(!isCall){
      isCall = true
      fn.call(this, ...args)
    }
  }
}

持续更新中…
如果你正在面试,希望能帮到你,如果你有更牛逼的方法,也欢迎一起交流~~~

微信:yuan_zi_xxx

你可能感兴趣的:(面试,面试,中间件,js,算法,函数闭包)