JS常見演算法題目

獨木成林發表於2018-06-20
 
最近收集了幾個經典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));

 

 

相關文章