JS算法笔试库

BSMST

1、数组去重:let ary=[1,2,2,1,3]; arr=[…new Set(ary)]

 var ary = [1,2,3,4,2,3,5,6,7,8,8];
    for(var i=0; i<ary.length-1; i++){
        for(var j = i+1; j < ary.length; j++){
            if(ary[i] === ary[j]){
                ary[j] = ary[ary.length-1]; 
                j--; 
                ary.length--;
            }
        }
    }

2、排序

1.快速排序算法:

var quickSort = function(arr) {
  if (arr.length <= 1) { return arr; }
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++){
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat([pivot], 
  quickSort(right));
};

2.冒泡排序算法:

function bubbleSort(myArr) {
  for (let i = 0; i < myArr.length - 1; i++) {
   for (let j = 0; j < myArr.length - 1 - i; j++) {
     // 要移动几次
     if (myArr[j] > myArr[j + 1]) {
       [myArr[j], myArr[j + 1]] = [myArr[j + 1], 
       myArr[j]];
     }
   }
 }
  return myArr;
}

3.插入排序算法

function insertSort (arr) {
  let length = arr.length;
  for (let i = 1; i < length; i++) {
    let key = arr[i], j = i - 1;
    while (arr[j] > key) {
      arr[j + 1] = arr[j];
      j--;
    }
    arr[j + 1] = key;
  }
  return arr;
}

3、js判断回文字符串

回文字符串:字符串从前往后读和从后往前读字符顺序是一致的。

判断一个字符串是不是回文字符串

function isPalindrome(str) {
     var str1 = str.split('').reverse().join('');
     return str1===str;
    }

判断字符串中的所有回文字符串

function palindromeStr(str) {
     var temp = '';
      var result=[];
      for(var i=0;i<str.length;i++){
          temp = '';
          for(var j=i;j<str.length;j++){
              temp+=str.charAt(j);
              if(isPalindrome(temp) && 
              result.indexOf(temp) == -1){
                  result.push(temp);
              }
          }
      }
      return result;
  }

判断字符串中的最长回文字符串

function palindromeLongestStr(str) {
      var temp = '';
       var longestStr='';
       for(var i=0;i<str.length;i++){
           temp = '';
           for(var j=i;j<str.length;j++){
               temp+=str.charAt(j);
               if(isPalindrome(temp) && 
               longestStr.length<temp.length){
                   longestStr=temp;
               }
           }
       }
       return longestStr;
    }

4、一个字符串,找出最长的回文字符串?

   function longest(str) {
      let palindStr = ""; //记录最长回文串
      let temp = ""; //记录当前回文串
      for (let i = 0; i < str.length; i++) { //i记录当前遍历字符串的开始位置,循环依次向后遍历
        temp = ""; //每次新的一轮开始时,将临时记录回文串的变量清空
        for (let j = i; j < str.length; j++) { //每次开始循环是以当前i所在的下标位置
        //为开始遍历字符串的起始位置,直到遍历到结束位置
          temp += str.charAt(j); //逐个增加字符串的长度
          if (isPalindrome(temp) && temp.length > palindStr.length) { //将当前的字符串传入
          //isPalindrome进行回文判断,如果是回文串,则判断当前回文串长度是否大于之前记录的
          //最长回文串的长度,如果大于之前的回文串,则更新之前的记录即可
            palindStr = temp; //更新回文串
          }
        }
      }
      return palindStr; //返回最终的最长的回文串
    }
    function isPalindrome(s) { //判断是否为回文串
      let rev = s.split('').reverse().join(''); //字符串逆转操作
      return rev === s;
    }
    //测试
    console.log(longest("ddabbade"));//输出dabbad

5、防抖与节流

节流
节流的意思是,规定时间内,只触发一次。比如我们设定500ms,在这个时间内,无论点击按钮多少次,它都只会触发一次。具体场景可以是抢购时候,由于有无数人 快速点击按钮,如果每次点击都发送请求,就会给服务器造成巨大的压力,但是我们进行节流后,就会大大减少请求的次数。

防抖
防抖的意思是,在连续的操作中,无论进行了多长时间,只有某一次的操作后在指定的时间内没有再操作,这一次才被判定有效。具体场景可以搜索框输入关键字过程中实时 请求服务器匹配搜索结果,如果不进行处理,那么就是输入框内容一直变化,导致一直发送请求。如果进行防抖处理,结果就是当我们输入内容完成后,一定时间(比如500ms)没有再 输入内容,这时再触发请求。

结合以上两种情况,回到我们最实际的场景,比如防止表单提交按钮被多次触发,我们应该选择使用节流而不是防抖方案。

防抖:
function debounce(func, wait) {
  let timeout;
  return function() {
    const context = this;
    const args = [...arguments];
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(context, args);
    }, wait);
  };
}
-------------------------------------------------
截流:
function throttle(func, wait) {
  let timeout;
  return function() {
    let context = this;
    let args = arguments;
    if (!timeout) {
      timeout = setTimeout(() => {
        timeout = null;
        func.apply(context, args);
      }, wait);
    }
  };
}

6、打印

    function Foo() {
       this.getName = function () {
          console.log('1') 
        }; 
        return this; 
      }
    Foo.getName = function () { 
      console.log('2'); 
    };
    Foo.prototype.getName = function () {
       console.log('3');
       };
    var getName = function () { console.log('4') };
    function getName() { console.log('5'); };

// 打印
Foo.getName(); 
getName(); 
Foo().getName();
getName(); 
new (Foo.getName)(); 
(new Foo()).getName();

241121

7、在react中创建防抖方法

import React, { Component } from 'react'//防抖方法
function debounce(fn, ms = 500) {
    let timeoutId
    return function () {
      clearTimeout(timeoutId)
      timeoutId = setTimeout(() => {
        fn.apply(this, arguments)
      }, ms)
    }
  }
  
export default class input extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue:''
        };

        this.isPhoneLegal = debounce(this.isPhoneLegal, 1000)//调用设定好的防抖方法
    };

    handleKeyUp = (e) => {
        this.isPhoneLegal(e.target.value) // 对用户输入进行判断
        this.setState({
            inputValue : e.target.value
        },()=>{
            console.log('tag', this.state.inputValue) // 实时获取
        })
    }
    isPhoneLegal  = (phone) => {
        console.log(phone)  // 防抖后获取的值
    } 
    
    render() {
        return (
            <div>
               <input 
                value={this.state.inputValue}  
                onChange={ this.handleKeyUp} 
                placeholder="请输入手机号"
                />
            </div>
        )
    }
}

8、实现 mergePromise 函数,把传进去的数组顺序先后执行,并且把返回的数据先后放到数组 data 中

const timeout = ms =>
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, ms)
  })

const ajax1 = () =>
  timeout(2000).then(() => {
    console.log('1')
    return 1
  })

const ajax2 = () =>
  timeout(1000).then(() => {
    console.log('2')
    return 2
  })

const ajax3 = () =>
  timeout(2000).then(() => {
    console.log('3')
    return 3
  })

const mergePromise = ajaxArray => {
  // 在这里实现你的代码
}

mergePromise([ajax1, ajax2, ajax3]).then(data => {
  console.log('done')  
  console.log(data) // data 为 [1, 2, 3]
})

// 分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]

// 解法 1
const mergePromise = ajaxArray => {
  // 在这里实现你的代码
  return new Promise(async function(resolve) {
    let data = []
    for (let it of ajaxArray) {
      let tmp = await it()
      data.push(tmp)
    }
    resolve(data)
  })
}

// 解法 2
const mergePromise = ajaxArray => {
  // 在这里实现你的代码
  var data = []
  var sequence = Promise.resolve()
  ajaxArray.forEach(function(item) {
    sequence = sequence.then(item).then(function(res) {
      data.push(res)
      return data
    })
  })

  return sequence
}

9、斐波那契数列

题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。斐波那契数列的定义如下:
f(0) = 0,f(1) = 1,f(n) = f(n-1)+f(n-2)
function fibonacci(n){
   if(n==0)return 0
   else if(n==1)return 1
   else return fibonacci(n-1) + fibonacci(n-2)
}

function fibonacci(n){
  var last = 1
  var last2 = 0
  var current = last2
  for(var i=1;i<=n;i++){
    last2 = last
    last = current
    current = last + last2
  }
  return current
}

function memozi(fn){
  var r = {}
  return function(n){
    if(r[n] == null){
      r[n] = fn(n)
      return r[n]
    }else{
        return r[n]
    }
  }
}

var fibfn = memozi(function(n){
    if(n==0){
        return 0
    }else if(n==1){
        return 1
    }else{
        return fibfn(n-1) + fibfn(n-2)
    }
})

10、JS限流调度器

实现JS限流调度器,方法add接收一个返回Promise的函数,
同时执行的任务数量不能超过两个。
```js
class Scheduler {
    async add(promiseFunc: () => Promise<void>): Promise<void> {
    }
}

const scheduler = new Scheduler()
const timeout = (time) => {
    return new Promise(r => setTimeout(r, time))
}
const addTask = (time, order) => {
    scheduler.add(() => timeout(time))
        .then(() => console.log(order))
}

addTask(1000, 1)
addTask(500, 2)
addTask(300, 3)
addTask(400, 4)
// log: 2 3 1 4
------------------------------------------------------------
答案:
class Scheduler {
    constructor() {
        this.concurrency = 0
        this.queue = []
    }
    async add(promiseFunc) {
        if (this.concurrency >= 2) {
            return new Promise(r => {
                this.queue.push(() => promiseFunc().then(r))
            })
        }
        this.concurrency += 1
        await promiseFunc()
        this.concurrency -= 1
        let next = this.queue.shift()
        if (next) {
            this.add(next)
        }
    }
}

const scheduler = new Scheduler()
const timeout = (time) => {
    return new Promise(r => setTimeout(r, time))
}
const addTask = (time, order) => {
    scheduler.add(() => timeout(time))
        .then(() => console.log(order))
}

addTask(1000, 1)
addTask(500, 2)
addTask(300, 3)
addTask(400, 4)

11、简单的实现Promise.all

function fn1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(1)
        }, 1000);
    })
}
function fn2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(2)
        }, 2000);
    })
}
PromiseAll([fn1(), fn2()]).then(res => {
    console.log(res)
}).catch(err => {
    console.log(err)
})

Promise.all([fn1(), fn2()]).then(res => {
    console.log(res)
}).catch(err=>{
    console.log(err)
})
------------------------------------------------------------------
答案:
function PromiseAll(list) {
    return new Promise((resolve, reject) => {
        let count = 0;
        let len = list.length;
        let result = [];
        list.forEach((item,index) => {
            item.then(res => {
                count++;
                result[index] = res;
                if (count === len) {
                    resolve(result);
                }
            }).catch(err => {
                reject(err)
            })
        })
    })
}

12、函数科里化

描述信息
实现如下函数add,使如下执行都等于9
add(2,3,4)=9
add(2)(3,4)=9
add(2)(3)(4)=9
add(2,3)(4)=9
-----------------------------
答案:
function curry(fn) {
  const params = [];
  const res = (...arg) => {
    params.push(...arg);
    if (params.length >= fn.length) {
      return fn(...params);
    }
    return res;
  };
  return res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值