数字马力编程笔试试题
这次数字马力校招的笔试题难度不大, 非常的基础, 一共有5道编程题, 其中最后一道是高亮字符串的, 没时间看了故没记住
其余四道题笔者的题解如下, 如果大家有更好的方法欢迎分享
1. 字符串匹配
题目: 判断字符串是否符合XXX-XXX-XXXX(X为数字), 返回Boolean值
例如 :
'110-110-1100' 返回 true,
'11a-11b-110c' 返回 ralse
'123-1-2' 返回 ralse
这道题也是非常的基础, 核心就是需要考虑NaN的情况, 题解如下:
function matchingStr(string) {
const numberArr = string.split("-");
const result = numberArr.map((item, index) => {
if (index === 2) {
return item.length === 4 && isNum(item);
} else {
return item.length === 3 && isNum(item);
}
});
return result.every((item) => item);
}
function isNum(str) {
// 需要考虑NaN的情况
return typeof +str === "number" && (+str).toString() !== "NaN";
}
2. 函数柯里化
题目: 实现一个curry函数, 完成以下效果:
const add = (a, b, c)=>a + b + c
curry(add)(1)(2)(3) === add(1,2,3)
函数柯里化也是笔试中非常常见的题目了, 像这道题, 给出了具体的函数, 便可以使用闭包和嵌套快速的去解题:
function add(a, b, c) {
return a + b + c;
}
function curry(add) {
return function addA(a) {
return function addB(b) {
return function addC(c) {
return add(a, b, c);
};
};
};
}
console.log(curry(add)(1)(2)(3) === add(1, 2, 3)); //true
不过笔者不是这么写的, 恰巧前几天在修言大佬的JavaScript 函数式编程实践指南中学习到了这一点, 此时正好派上用场(强推这本书, 干货满满)
扩展 : 实现一个通用的curry函数
如何去实现一个通用的柯里化函数呢?
分三步走:
- 获取函数参数的数量
- 自动分层嵌套函数: 有多少参数,就有多少层嵌套
- 在嵌套的最后一程, 调用回调函数. 传入所有入参
function commonCurry(func, arity = func.length) {
//定义一个递归式generateCurried
function generateCurried(preArgs) {
// generateCurried 函数必定返回一层嵌套
return function curried(nextArg) {
// 统计目前“已记忆”+“未记忆”的参数
const args = [...preArgs, nextArg];
// 已经记忆了所有的参数
if (args.length >= arity) {
return func(...args);
} else {
// 递归调用
return generateCurried(args);
}
};
}
// 起始传参为空数组,表示“目前还没有记住任何参数”
return generateCurried([]);
}
3. sqrt函数
题目: 实现
sqrt
函数, 计算一个数的平方根例如:
sqrt(9) === 3
这个感觉是数学上的问题了, 当时直接懵了, 试了一下直接使用 Math.sqrt()
,没想到直接通过了, 这里给出gpt提供的代码
// 牛顿迭代法
function sqrt(x) {
if (x === 0) return 0; // 若x为0,则直接返回0
let guess = x; // 首先假设猜测一个平方根
let prevGuess; // 上一次的猜测值
let threshold = 1e-6; // 设置一个阈值,用于判断迭代的精度
do {
prevGuess = guess; // 将上一次的猜测值保存
// 使用牛顿迭代法更新猜测值
guess = (guess + x / guess) / 2;
// 判断猜测值是否已经达到了足够的精度
} while (Math.abs(guess - prevGuess) > threshold);
return guess;
}
console.log(sqrt(9)); //3
4. RGB转HEX
题目: 实现
rgbToHex()
函数, 将 rgb 转为 hex例如:
rgbToHex('rgb(255,255,255)') === '#ffffff'
笔者的大部分时间都花在了这道题上, 因为当时忘了10进制怎么去转16进制了, 属实是折磨坏了, 下面是我第一次的题解:
//核心为10进制转16进制: 除16取余法
function rgbToHex(string) {
const hexMap = {
10: "a",
11: "b",
12: "c",
13: "d",
14: "e",
15: "f",
};
//拆分为三个数字的数组
const rgbSpt = string.split(",");
rgbSpt[0] = rgbSpt[0].slice(4);
rgbSpt[2] = rgbSpt[2].slice(0, rgbSpt[2].length - 1);
// string转换为number
const rgbNumber = rgbSpt.map((item) => +item);
let result = "#";
rgbNumber.forEach((item) => {
// 为0不走循环,填充为00
if (item === 0) result += "00";
// 小于10 走一次循环,填充一个0
else if (item < 10) result += "0";
while (item !== 0) {
// 取余数
let remainder = item % 16;
// 大于等于10的转为字母表示
remainder = remainder >= 10 ? hexMap[remainder] : remainder;
result += remainder;
item = Math.floor(item / 16);
}
});
return result;
}
console.log(rgbToHex("rgb(255,255,255)")); //#ffffff
后来发现根本不用自己去实现10进制转16进制, 只需要调用Number
原型上的toString
方法即可
function rgbToHex(r, g, b) {
let red = r.toString(16);
let green = g.toString(16);
let blue = b.toString(16);
if (red.length == 1) red = "0" + red;
if (green.length == 1) green = "0" + green;
if (blue.length == 1) blue = "0" + blue;
return "#" + red + green + blue;
}
const red = 255;
const green = 0;
const blue = 0;
const hex = rgbToHex(red, green, blue);
console.log(hex); //#ff0000
以上就是这次笔试的编程题了, 欢迎各位大佬给出建议~