目录
[typeof this !== 'function'](#typeof this !== 'function')
[context = context || window](#context = context || window)
[context._this = this](#context._this = this)
[delete context._this](#delete context._this)
[bind: return _this.apply(context, [...arguments].slice(1));](#bind: return _this.apply(context, [...arguments].slice(1));)
[!arr|| arr == null || typeof arr != 'object'](#!arr|| arr == null || typeof arr != 'object')
[arr instanceof Array ? [] : {}](#arr instanceof Array ? [] : {})
[result[key] = cloneDeep(arr[key])](#result[key] = cloneDeep(arr[key]))
[千位分割:num.slice(render, len).match(/\d{3}/g).join(',')](#千位分割:num.slice(render, len).match(/\d{3}/g).join(','))
[k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标](#k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标)
ES6
改变this
call
typeof this !== 'function'
context = context || window
context._this = this
delete context._this
javascript
// 给function的原型上面添加一个 _call 方法
Function.prototype._call = function (context) {
// 判断调用者是否是一个函数 this 就是调用者
if (typeof this !== 'function') {
throw new TypeError('what is to be a function')
}
// 如果有 context 传参就是传参者 没有就是window
context = context || window
// 保存当前调用的函数
context._this = this
// 截取传过来的参数
/*
arguments
a: 1
fn: ƒ fns()
*/
// 通过 slice 来截取传过来的参数
const local = [...arguments].slice(1)
// 传入参数调用函数
let result = context._this(...local)
// 删属性
delete context._this
return result
}
let obj = { a: 1 }
function fns(a, b) {
console.log(a, b);
console.log(this)
}
fns._call(obj, 23, 555)
bind: return _this.apply(context, [...arguments].slice(1));
深拷贝
!arr|| arr == null || typeof arr != 'object'
arr instanceof Array ? [] : {}
for (const key in arr)
result[key] = cloneDeep(arr[key])
javascript
function cloneDeep(arr = {}) {
// 终止递归
if (!arr|| arr == null || typeof arr != 'object' ) return arr
// 用 instanceof 判断原型链上是否有该类型的原型 是 Array => [] ! Arrays =>{}
let result=arr instanceof Array ? [] : {}
// forin 循环对象的key值
for (const key in arr) {
// 对象 key 赋值 result
result[key] = cloneDeep(arr[key])
}
return result
}
算法
合法的URL
URL结构一般包括协议、主机名、主机端口、路径、请求信息、哈希
- 域名不区分大小写:"www"子域名(可选)、二级域名、"com"顶级域名
- 只能包含字母(a-z、A-Z)、数字(0-9)和连字符(-)(但-不能再首尾)
javascript
https://www.bilibili.com/video/BV1F54y1N74E/?spm_id_from=333.337.search-card.all.click&vd_source=6fd32175adc98c97cd87300d3aed81ea
//开始: ^
//协议: http(s)?:\/\/
//域名: [a-zA-Z0-9]+-[a-zA-Z0-9]+|[a-zA-Z0-9]+
//顶级域名 如com cn,2-6位: [a-zA-Z]{2,6}
//端口 数字: (:\d+)?
//路径 任意字符 如 /login: (\/.+)?
//哈希 ? 和 # ,如?age=1: (\?.+)?(#.+)?
//结束: $
// https:// www.bilibili com /video/BV1F54y1N74E ?spm..
/^(http(s)?:\/\/)?(([a-zA-Z0-9]+-[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)+([a-zA-Z]{2,6})(:\d+)?(\/.+)?(\?.+)?(#.+)?$/.test(url)
千位分割:num.slice(render, len).match(/\d{3}/g).join(',')
javascript
const format = (n) => {
let num = n.toString() // 拿到传进来的 number 数字 进行 toString
let len = num.length // 在拿到字符串的长度
// 当传进来的结果小于 3 也就是 千位还把结果返回出去 小于3 不足以分割
if (len < 3) {
return num
} else {
let render = len % 3 //传入 number 的长度 是否能被 3 整除
if (render > 0) { // 说明不是3的整数倍
return num.slice(0, render) + ',' + num.slice(render, len).match(/\d{3}/g).join(',')
} else {
return num.slice(0, len).match(/\d{3}/g).join(',')
}
}
}
let str = format(298000)
console.log(str)
公司*
用友sp
一面【二选一】
数组相邻和最大的对应两个元素
千位分割【无负数,含小数】
javascript
function formatNumberWithCommas(number) {
// 将数字转换为字符串
const numStr = number.toString();
// 判断是否为小数
const isDecimal = numStr.includes('.');
// 如果是小数,分割整数部分和小数部分
let integerPart = numStr;
let decimalPart = '';
if (isDecimal) {
[integerPart, decimalPart] = numStr.split('.');
}
// 使用贪心算法从右往左插入逗号
let formattedInteger = '';
let count = 0;
for (let i = integerPart.length - 1; i >= 0; i--) {
formattedInteger = integerPart[i] + formattedInteger;
count++;
if (count === 3 && i !== 0) {
formattedInteger = ',' + formattedInteger;
count = 0;
}
}
// 如果有小数部分,添加回小数点和小数部分
const formattedNumber = isDecimal
? formattedInteger + '.' + decimalPart
: formattedInteger;
return formattedNumber;
}
// 测试
const number1 = -1234567.89;
const number2 = 12345.67;
const number3 = 123456;
console.log(formatNumberWithCommas(number1)); // 输出 "-1,234,567.89"
console.log(formatNumberWithCommas(number2)); // 输出 "12,345.67"
console.log(formatNumberWithCommas(number3)); // 输出 "123,456"
二面
华容道:BFS
k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标
swap(t[k],t[a*3+b]);
distance
数组用于记录每个状态距离初始状态的步数。
在华容道问题中,每次移动一次,就相当于从一个状态转移到了另一个状态。
BFS的核心思想是从初始状态开始,逐步地将可能的状态加入队列,并记录每个状态距离初始状态经过的步数。
cpp
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
int bfs(string start)
{
string end = "12345678x";
queue<string> q;
unordered_map<string,int> d;
q.push(start);
d[start] = 0;
int dx[] = {-1,0,1,0}, dy[] = {0,1,0,-1};
//宽搜过程
while(q.size())
{
auto t = q.front();
q.pop();
int distance = d[t];
if(t == end) return distance;
//状态转移
//找到x的位置
int k = t.find('x'); //返回x的下标
int x = k / 3, y = k % 3; //一维数组下标转化到二维数组中的坐标
//枚举上下左右四个方向
for(int i = 0; i < 4; i ++ )
{
int a = x + dx[i], b = y + dy[i];
if(a >= 0 && a < 3 && b >= 0 && b < 3)
{
swap(t[k],t[a*3+b]);
if(!d.count(t)) //当前更新的状态没有搜到过
{
d[t] = distance + 1; //更新当前距离
q.push(t); //把新的状态加到队列中
}
swap(t[k],t[a*3+b]); //状态恢复
}
}
}
return -1;
}
int main()
{
string start;
for(int i = 0 ; i < 9; i ++ )
{
char c;
cin >> c;
start += c;
}
cout << bfs(start) << endl;
return 0;
}
版本号排序:【滴滴提前批】
javascript
// 假设有一个版本号数组
const versionNumbers = ["1.0.2", "1.1.0", "2.0.0", "1.0.1"];
// 定义一个比较函数来进行版本号排序
function compareVersions(versionA, versionB) {
const partsA = versionA.split('.').map(Number);
const partsB = versionB.split('.').map(Number);
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
const partA = partsA[i] || 0;
const partB = partsB[i] || 0;
if (partA < partB) return -1;
if (partA > partB) return 1;
}
return 0;
}
// 使用比较函数对版本号数组进行排序
const sortedVersions = versionNumbers.sort(compareVersions);
// 打印排序后的版本号数组
console.log(sortedVersions);