前端15k需要会的手写JS代码题(多种解题方法)

Posted 十九万里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端15k需要会的手写JS代码题(多种解题方法)相关的知识,希望对你有一定的参考价值。

话不多说 直接上代码!!!

1、JS实现一个函数 完成超过方位的两个大整数相加功能

// 主要思路1:将数字转换为字符串,然后每个字符串在按位相加。

function bigNumberAdd(number1, number2) {
  let result = '', // 保存最后结果
    carry = false; // 保留进位结果

  // 将字符串转换为数组
  number1 = number1.split('');
  number2 = number2.split('');

  // 当数组的长度都变为0,并且最终不再进位时,结束循环
  while (number1.length || number2.length || carry) {
    // 每次将最后的数字进行相加,使用~~的好处是,即使返回值为 undefined 也能转换为 0
    carry += ~~number1.pop() + ~~number2.pop();

    // 取加法结果的个位加入最终结果
    result = (carry % 10) + result;

    // 判断是否需要进位,true 和 false 的值在加法中会被转换为 1 和 0
    carry = carry > 9;
  }

  // 返回最终结果
  return result;
}

//思路2:转化成数组。因为数组的方法比较多
function sum(str1, str2) {
    const arr1 = str1.split(''),arr2 = str2.split('');
    const len1 = arr1.length,len2 = arr2.length;
    const maxLen = Math.max(len1, len2);
    let res = [];
    let flag = false;
    for(let i = 0; i < maxLen; i++) {
        let temp;
        let num1 = arr1.pop() , num2 = arr2.pop();
        num1 = num1 ? num1 : 0;
        num2 = num2 ? num2 : 0;
        if(flag) {
            temp =  parseInt(num1) + parseInt(num2) + 1;
        } else {
            temp =  parseInt(num1) + parseInt(num2);
        }
        if(parseInt(temp/10) > 0) {
            // 有进位
            res.push(temp%10);
            flag = true;
        } else {
            res.push(temp);
            flag = false;
        }
        if( i == maxLen -1 && flag) {
            res.push(1);
        }
    }
    return res.reverse().join('');
}

// 验证
sum('987654321111234','99900334444') // '987754221445678'

参考:js实现两个大数相加
参考:算法总结

// 最简单的代码:
function add(a,b){
    // 保存最终结果
    var res='';

    // 保存两位相加的结果 和 进位值
    var c=0;

    // 字符串转数组
    a = a.split('');

    while (a.length || b.length || c){
        // ~~ 用来把String类型 转为 Number类型
        // 把两位相加的结果 和 进位值相加
        c += ~~a.pop() + ~~b.pop();

        // 取余,把余数拼接到最终结果中
        res = c % 10 + res;

        // 保存进位,true 或者 false
        c = c>9;
    }
    return res;
}
add('11111111111111111','22222222222222222');

参考:JavaScript实现 超范围的数 相加

2、JS实现数组扁平化

// 这一种方法通过递归来实现,当元素为数组时递归调用,兼容性好
function flattenArray(array) {
  if (!Array.isArray(array)) return;

  let result = [];

  result = array.reduce(function (pre, item) {
    // 判断元素是否为数组,如果为数组则递归调用,如果不是则加入结果数组中
    return pre.concat(Array.isArray(item) ? flattenArray(item) : item);
  }, []);

  return result;
}

// 这一种方法是利用了 toString 方法,它的一个缺点是改变了元素的类型,只适合于数组中元素都是整数的情况
function flattenArray(array) {
  return array
    .toString()
    .split(',')
    .map(function (item) {
      return +item;
    });
}

3、实现数组的去重

//unique是数组去重的方法
function unique(array) {
//判断不是数组直接返回
  if (!Array.isArray(array) || array.length <= 1) return;

  var result = [];
//遍历数组的indexOF 
  array.forEach(function (item) {
    if (result.indexOf(item) === -1) {
      result.push(item);
    }
  });

  return result;
}

// ES6中可以使用箭头函数
function unique(array) {
  if (!Array.isArray(array) || array.length <= 1) return;

  return [...new Set(array)];
}

//衍生 

4、求数组的最大值和最小值

var arr = [6, 4, 1, 8, 2, 11, 23];
console.log(Math.max.apply(null, arr));
console.log(Math.min.apply(null, arr));
//最原始的方法就是把他循环比较一遍 筛选出最大和最小的

注:
如果有任一参数不能被转换为数值,则结果为 NaN。
max 是 Math 的静态方法,所以应该像这样使用:Math.max(),而不是作为 Math 实例的方法 (简单的来说,就是不使用 new )
如果没有参数,则结果为 -Infinity (注意是负无穷大)

5、求两个数的最大公约数

// 基本思想是采用辗转相除的方法,用大的数去除以小的那个数,
// 然后再用小的数去除以的得到的余数,一直这样递归下去,直到余数为0时,
// 最后的被除数就是两个数的最大公约数。

function getMaxCommonDivisor(a, b) {
  if (b === 0) return a;

  return getMaxCommonDivisor(b, a % b);
}

6、求两个数的最小公倍数

// 基本思想是采用将两个数相乘,然后除以它们的最大公约数

function getMinCommonMultiple(a, b) {
  return (a * b) / getMaxCommonDivisor(a, b);
}

7、手写实现Indexof方法

// 原理就是循环遍历数组,取出下标,递增放到新的数组里
function indexFun(array, val) {
  if (!Array.isArray(array)) return;

  let length = array.length;

  for (let i = 0; i < length; i++) {
    if (array[i] === val) {
      return i;
    }
  }

  return -1;
}

8、JS判断一个字符串为回文串

// “回文字符串”是一个正读和反读都一样的字符串。
function isPalindrome(str) {
  let reg = /[\\W_]/g, // 匹配所有非单词的字符以及下划线
    newStr = str.replace(reg, '').toLowerCase(), // 替换为空字符并将大写字母转换为小写
    reverseStr = newStr.split('').reverse().join(''); // 将字符串反转

  return reverseStr === newStr;
}

9、 实现一个累加函数的功能比如 sum(1,2,3)(2).valueOf()

function sum(...args) {
  let result = 0;

  result = args.reduce(function (pre, item) {
    return pre + item;
  }, 0);

  let add = function (...args) {
    result = args.reduce(function (pre, item) {
      return pre + item;
    }, result);

    return add;
  };

  add.valueOf = function () {
    console.log(result);
  };

  return add;
}

10、 使用 reduce 方法实现 forEach、map、filter

// forEach
function forEachUseReduce(array, handler) {
  array.reduce(function (pre, item, index) {
    handler(item, index);
  });
}

// map
function mapUseReduce(array, handler) {
  let result = [];

  array.reduce(function (pre, item, index) {
    let mapItem = handler(item, index);
    result.push(mapItem);
  });

  return result;
}

// filter
function filterUseReduce(array, handler) {
  let result = [];

  array.reduce(function (pre, item, index) {
    if (handler(item, index)) {
      result.push(item);
    }
  });

  return result;
}

11、设计一个简单的任务队列,要求分别在 1,3,4 秒后打印出 “1”, “2”, “3”

class Queue {
  constructor() {
    this.queue = [];
    this.time = 0;
  }

  addTask(task, t) {
    this.time += t;
    this.queue.push([task, this.time]);
    return this;
  }

  start() {
    this.queue.forEach((item) => {
      setTimeout(() => {
        item[0]();
      }, item[1]);
    });
  }
}

12、 如何查找一篇英文文章中出现频率最高的单词?

function findMostWord(article) {
  // 合法性判断
  if (!article) return;

  // 参数处理
  article = article.trim().toLowerCase();

  let wordList = article.match(/[a-z]+/g),
    visited = [],
    maxNum = 0,
    maxWord = '';

  article = ' ' + wordList.join('  ') + ' ';

  // 遍历判断单词出现次数
  wordList.forEach(function (item) {
    if (visited.indexOf(item) < 0) {
      let word = new RegExp(' ' + item + ' ', 'g'),
        num = article.match(word).length;

      if (num > maxNum) {
        maxNum = num;
        maxWord = item;
      }
    }
  });

  return maxWord + '  ' + maxNum;
}

13、找出数组中重复出现过的元素

    // 例如:[1,2,4,4,3,3,1,5,3]
    // 输出:[1,3,4]
    let arr = [1, 2, 4, 4, 3, 3, 1, 5, 3];
    
    // 方法一
    function repeat1(arr){
    	var result = [], map = {};
    	arr.map(function(num){
    	if(map[num] === 1) result.push(num); // 等于1说明之前出现过一次 这次重复出现了
    		map[num] = (map[num] || 0) + 1; // 微妙之处 开始第一次出现无值 记为 0 + 1 = 1 下一次从1开始累加
    	});
    	return result;
    }
    console.log(repeat1(arr));
    
    
    
    // 方法二
    function repeat(arr) {
        let result = arr.filter((x, i, self) => {
            return self.indexOf(x) === i && self.lastIndexOf(x) !== i
        }); // 
        return result;
    }
    console.log(repeat(arr));
复制代码

14.数组中按照数字重复出现的次数进行排序

    // 如果次数相同 则按照值排序 比如  2, 2, 2和 1, 1, 1  应排序为 [1, 1, 1, 2, 2, 2]
    // 比如 [1,2,1,2,1,3,4,5,4,5,5,2,2] => [3, 4, 4, 1, 1, 1, 5, 5, 5, 2, 2, 2, 2]
 
    let arr = [9, 7, 7, 1, 2, 1, 2, 1, 3, 4, 5, 4, 5, 5, 2, 2];
    function sortArray(arr) {
        let obj = {};
        let newArr = [];
        for(let i = 0; i < arr.length; i++) {
            let cur = arr[i];
            if(obj[cur]){
            obj[cur].push(cur);
            continue;
            }
            obj[cur] = [cur];
        }
        for(let k in obj) {
            if(obj.hasOwnProperty(k)) {
            newArr.push(obj[k])
            }
        }
        newArr.sort((a, b) => {
            if(a.length === b.length){
            return a[0] - b[0];
            }
            return a.length - b.length;
        });
        newArr = newArr.reduce((prev, cur) => prev.concat(cur));
        return newArr;
    }
      console.log(sortArray(arr)); // [ 3, 9, 4, 4, 7, 7, 1, 1, 1, 5, 5, 5, 2

以上是关于前端15k需要会的手写JS代码题(多种解题方法)的主要内容,如果未能解决你的问题,请参考以下文章

前端面试题之手写promise

第28题手写抽奖算法

堆和优先级队列4:不泡妹子都要会的LeetCode7道题之二

JS手写面试题 --- Promise 以及相关方法的实现

前端面试题之手写代码篇

JS手写面试题 --- 类数组转化为数组的方法