过来看字节手写题——数组去重和大数相加🚀🚀🚀

435 阅读4分钟

前言

以下题目来自学长字节面试 , 做一下整理

数组去重

拷打一

直接使用es6里面的Set 和 ...运算符(解构运算符)

let arr = [1,2,3,4,56,7,1,2,3,4,56,7]

let newArr = [...new Set(arr)]

console.log(newArr)

写这个展现你知道 ES 语法 Set

拷打二

如果是这样的数组怎么办 ?

let arr = [1, 1, '2', 3, 1, 2,
    { name: '张三', id: { n: 1 } },
    { name: '张三', id: { n: 1 } },
    { name: '张三', id: { n: 2 } },
]

这里,虽然数组中有两个看起来一样的对象 { name: '张三', id: { n: 1 } },但它们在内存中是不同的对象,具有不同的内存地址,所以 Set 会把它们当作不同的元素保留下来,无法实现对对象元素的去重。

首先你要理解Set

Set 是 ES6 引入的一种新的数据结构,它类似于数组,但成员的值都是唯一的,没有重复的值。

当使用 new Set() 创建一个 Set 实例时,传入的可迭代对象(如数组)中的重复元素会被自动去除。

不过,Set 判断元素是否重复是基于严格相等(===)比较的。

对于基本数据类型(如 Number、String、Boolean 等),Set 能正确判断是否重复,但对于引用数据类型(如 Object、Array 等),只要它们的内存地址不同,即使内容看起来一样,Set 也会认为它们是不同的元素。

解法 :

let arr = [
    1, 1, '2', 3, 1, 2,
    { name: '张三', id: { n: 1 } },
    { name: '张三', id: { n: 1 } },
    { name: '张三', id: { n: 2 } }
];
const arr1 = arr.map((item) => {
    return JSON.stringify(item);
});
const arr2 = [...new Set(arr1)];
console.log(arr2);

拷打三

问题 :

如果是 {id:{n:1},name:'张三'}怎么办 ?

可以编写一个函数,先将对象的属性名排序,然后按照排序后的顺序构建新对象,最后对新对象进行字符串化。

/**
 * 递归地对对象的属性进行字母顺序排序。
 * 
 * 该函数接受一个对象并返回一个新的对象,其属性按字母顺序排序。
 * 如果对象包含嵌套对象或数组,它们也会被递归地按字母顺序排序。
 * 
 * @param obj - 要排序的对象。
 * @returns 返回一个属性按字母顺序排序的新对象。如果输入不是对象,则直接返回输入。
 */
function sortObject(obj) {
    // 检查 obj 是否为对象且不为 null,如果不是,直接返回 obj
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }
    // 如果 obj 是数组,对每个元素递归调用 sortObject 并返回新数组
    if (Array.isArray(obj)) {
        return obj.map(sortObject);
    }
    // 创建一个新对象以存储排序后的属性
    const sortedObj = {};
    // 获取对象的键,按字母顺序排序,并对每个属性递归调用 sortObject,将结果存储在新对象中
    Object.keys(obj).sort().forEach(key => {
        sortedObj[key] = sortObject(obj[key]);
    });
    // 返回按字母顺序排序属性的对象
    return sortedObj;
}
let arr = [
    { id: { n: 1 }, name: '张三' },
    { name: '张三', id: { n: 1 } },
    { id: { n: 2 }, name: '李四' }
];

const arr1 = arr.map(item => JSON.stringify(sortObject(item)));
const arr2 = [...new Set(arr1)];
const result = arr2.map(item => JSON.parse(item));
console.log(result);

大数相加

实现大数相加

使用 BigInt (🤡)

// 创建 BigInt 类型的数值,通过在数字后面加 n 或者使用 BigInt() 函数
const bigNum1 = 9007199254740991n; 
const bigNum2 = BigInt(9007199254740991); 

// 进行加法运算
const sum = bigNum1 + bigNum2;

console.log(sum); 
  • BigInt 类型的数值创建有两种方式:一是在普通整数后面直接加 n;二是使用 BigInt() 函数将其他类型的值转换为 BigInt 类型。
  • 对 BigInt 类型的数值进行加法运算和普通数字一样直接使用 + 运算符,而且不会出现精度丢失问题。

手写

let n = 9007199254740992 // 2^53
let m = 71542122// 定义两个数字 , 相加结果是9007199326283114

function add(x,y){
    let res = 0
    let carry = 0
    let ans = ''
    x = x.toString();
    y = y.toString()
    let maxLenght  = Math.max(x.length,y.length)
    for(let i = 1; i<= maxLenght; i++){
        // 取出每一位的值
        let a = parseInt(x[x.length-i]||0);
        let b = parseInt(y[y.length-i]||0);
        // 算出每一位的结果
        res = a + b + carry;
        // 满10进位 
        carry = Math.floor(res/10);
        // 取余即当前位置的数 
        ans = (res%10) + ans;
    }

    if(carry>0) ans += carry ;

    return ans ;
}

console.log(add(n,m))