• JS常见算法题目


     
    最近收集了几个经典JS题目,比较有代表性,分享一下:
     
    1.xiaoshuo-ss-sfff-fe  变为驼峰xiaoshuoSsSfffFe
    function getCamelCase(str) {
        var arr = str.split( '-' );
        return arr.map( function( item, index ) {
            console.log(item)
            if( index === 0 ){
                return item;
            }else{
                return item.charAt(0).toUpperCase() + item.slice( 1 );
            }
        }).join('');
    }
        console.log(getCamelCase("xiaoshuo-ss-sfff-fe"))
    正则写法:
    function getCamelCase( str ){
       return str.replace( /-([a-z])/g , function( all, i){    // 注意正则中的(),这里可以匹配到  -s 和s
                    return i.toUpperCase();                        
           }   )
    }
     如果这道题要求反向转化
    function getCase(str) {
        var arr = str.split('');  // 每一个字符组成数组
        str = arr.map(function ( item ){
            if( item.toUpperCase() === item ){
                return '-' + item.toLowerCase();
            }else{
                return item;
            }
        }).join( '' );
        return str;
     
    }
        console.log(getCamelCase("xiaoShuoWangXiao"))
    正则写法
    function getCase(){
      return str.replace( /[A-Z]/g  , function(i) {
           retrun '-' + i.toLowerCase();
      })
    }
    2.数组去重
    ES6 set法:
    var arry =[1,25,15,1,2,15,5,15,25,35,1]
    var set =new Set(arry)
    console.log([...set])
    或者  简写为
    [...new Set(arr)]
    传统写法之一:
    function qc(arr){
      var n = []; //一个新数组
      for(var i = 0;i<array.length;i++){         //也可以写x in array   x是迭代序号
          if(n.indexOf(array[i) === -1){  //检测到没有  则添加
               n.push(array[i)
            }
        }
       return n;
    }
    3.统计字符串中出现最多的字母
    循环一下字符串,第一次出现
    /**
    * 获取字符串中出现次数最多的字母
    * @param {String} str
    */
    function getChar(str) {
        if (typeof str !== 'string') return // 判断参数是否为字符串
        const obj = new Object() // 键为字母,值为次数
        for (let i = 0; i < str.length; i ++) { // 遍历字符串每一个字母
            let char = str.charAt(i) // 当前字母
            obj[char] = obj[char] || 0 // 保证初始值为0
            obj[char] ++ // 次数加1
        }
        let maxChar // 存储字母
        let maxNum = 0 // maxChar字母对应的次数
        for(let key in obj) { // 遍历obj
            if (obj[key] > maxNum) {
                maxChar = key // 比较后存储次数多的字母
                maxNum = obj[key] // 以及它对应的次数
            }
        }
        return maxChar // 返回结果
    }
     
    let str = 'aabbbccdd'
    console.log('出现次数最多的字母为:' + getChar(str))
    4.字符串反序
    首先将字符串序列化成数组,通过数组方法对数组反序,最后把数组转换成字符串。
    'say I love U'.split('').reverse().join('')   //  U evol I yas
    5.深拷贝
    浅拷贝只需要Object.assign();
    符合json要求(双引号)的对象深拷贝:
    JSON.parse(JSON.stringify(obj)
    不严格符合json的对象的深拷贝:
        function  deepCopy(src, r) {
            var r = r || {};
            for(var prop in src){
                // console.log(prop)
                if(typeof src[prop] === 'object'){ // 是对象  需要深拷贝
                    if (src[prop].constructor === Array){
                        // console.log("数组");
                        r[prop]=[];
                    }else{
                        // console.log("对象");
                        r[prop]={};
                    }
                    deepCopy(src[prop], r[prop]);
                }else{ // 非对象,直接拷贝
                    r[prop] = src[prop];
                }
            }
            return r;
        }
    6.合并多个有序数组
    不考虑去重:
    var arr = [[1, 2], [0, 3, 5], [-1, 4]];
    arr = arr
    .reduce((a, b) => a.concat(b), [])
    .sort((a, b) => a - b); // 如果需要从小到大排序加上这个
     
    console.log(arr);   //  输出 [-1, 0, 1, 2, 3, 4, 5]
    考虑去重(数组转化为对象,利用对象键名唯一性,然后.keys一次性取键名)
    var arr = [[1, 2], [0, 3, 5], [-1, 4]];
    var obj = {};
     
    arr = arr
        .forEach(item => item.forEach(function(num) {
            obj[num] = true;
        }));
    arr = Object
        .keys(obj)
        .map(num => +num) // 这行主要是将键名取出来之后,数组中全部是字符串,将其都转成数字,以便后面排序
        .sort((a, b) => a - b);
     
    console.log(arr);
    7.数组排序
    var arr = [1,25,3,85,4,0]
    arr.sort((m,n)=>{
    if(m>n){
         return 1       //顺序改变
      }else{
         return -1        //顺序不改变
      }
    })
    console.log(arr)  // [0, 1, 3, 4, 25, 85]
    也可以简化为
    var arr = [1,25,3,85,4,0]
    arr.sort((m,n)=>{
    if(m>n){
         return m-n   // m若大于n,m-n则是正数,反正是负数  和上面一样道理
      }})
    console.log(arr)  // [0, 1, 3, 4, 25, 85]
    同理:
    [{'name': '张三', age: 16},{'name': '李四', age: 45},{'name': '王五', age: 19},{'name': '赵六', age: 6}]  按年龄排序
    var arr = [{'name': '张三', age: 16},{'name': '李四', age: 45},{'name': '王五', age: 19},{'name': '赵六', age: 6}]
    arr.sort((m,n)=>{
         if(m.age>n.age){
            return m.age-n.age
         }
    })
    console.log(arr)    // [{name: "赵六", age: 6},{name: "张三", age: 16},{name: "王五", age: 19},{name: "李四", age: 45}]
    8.约瑟夫环问题
    编号为1到100的一百个人围成一圈,以123123的方式进行报数,数到3的人自动退出圈子,剩下的人继续报数,问最后剩下的人编号为几?
     
    递归解法:
    参考:
    根据这2篇文章可得到下面的思路:
    设:n为总人数   报数出环数字为k(123123的3)  i为第i次出环
    当i=1时,  f(n,k,i) = (n+k-1)%n
    当i!=1时,  f(n,k,i)= ( f(n-1,k,i-1)+k )%n
    简单来说, 这一轮=(上一轮+k)%n
    按照这个公式,递归就很好写了。   
     
    编号为1到100,报数逢3退出,注意解法中数组下标是从0开始的
     1     // 总人数n  报数出环数字k   n=100 k=3 第i个人出环
     2     function josephus(n,k,i) {
     3         if(i==1){
     4             return (n+k-1)%n;
     5         }else{
     6             return (josephus(n-1, k,i-1) + k)%n;
     7         }
     8     }
     9    for(var i=1;i<=100;i++){
    10         console.log("第"+i+"次出环,下标为:"+josephus(100,3,i))
    11    }
    12    // 第100次:下标为90的人出环  他的编号是91 (别忘了加1)
     另一种解法:
    这种方式比较简单,把编号组装为一个数组,设置一个浮标k,123的循环。每到3时将指向的值移除即可。
    编号为1到100,报数逢3退出
     1     function josephus2 (n,k){
     2         var players = [];
     3         for(var i=1;i<=n;i++){   // 组成数组
     4             players.push(i);
     5         }
     6         var flag=0;
     7         while(players.length>1){
     8             var outNum = 0;  //本次循环已出局人数,便于定位元素位置
     9             var len = players.length;
    10             for(var i=0;i<len;i++){
    11                 flag++;
    12                 if(flag==k){
    13                     flag=0;
    14                     console.log("出局:"+players[i-outNum]+"本次循环已出局人数:"+outNum);
    15                     // i循环时受数组长度影响 每从头开始时i变为0; 但flag始终是123..k  123..k 固定循环,不受数组影响  ,
    16                     players.splice(i-outNum,1);
    17                     outNum++;
    18                 }
    19             }
    20         }
    21         return players[0];
    22     }
    23     console.log(josephus2(100,3));
     
  • 相关阅读:
    js中定时器2
    js中定时器之一
    js中的Event对象
    hdu 1041(递推,大数)
    hdu 1130,hdu 1131(卡特兰数,大数)
    hdu 2044-2050 递推专题
    hdu 3078(LCA的在线算法)
    hdu 1806(线段树区间合并)
    hdu 3308(线段树区间合并)
    poj 2452(RMQ+二分查找)
  • 原文地址:https://www.cnblogs.com/dmcl/p/9204168.html
Copyright © 2020-2023  润新知