1. 程式人生 > 實用技巧 >JS基礎演算法題(二)

JS基礎演算法題(二)

1.1陣列去重的五種方法

陣列去重:將陣列中重複的元素去掉

  • JS陣列沒有刪除具體元素的刪除(只能刪掉值,刪不掉元素的索引),可以使用另外一個結構來進行儲存

    • 新陣列

    • 新物件

  • JS陣列雖然本質可以刪除第一個和最後一個元素,可以利用

  • 這一特性,交換當前重複的元素到最後,然後進行刪除(pop() 或者length--)

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    
    <body>
        <script>
            var arr = [20, 66, 88, 25, 66, 90, 88, 50];// [20,25,66,88,90,50]
    
            //1.排序法 : 最好理解
    
            // //1.1 對陣列排序
            // arr.sort(function(a,b){
            //     return a-b;
            // });
            // console.log(arr);
            // //1.2 宣告空陣列儲存去重後的陣列
            // var newArr = [];
            // //1.3 遍歷arr,檢查arr[i]與arr[i+1]是否相等
            // for(var i = 0;i<arr.length;i++){
            //     if(arr[i] != arr[i+1]){
            //         newArr[newArr.length] = arr[i];
            //     };
            // };
            // console.log(newArr);
    
    
    
    
            //2.開關思想(假設成立法)
    
            // //2.1 宣告空陣列儲存去重後的陣列
            // var newArr = [];
            // //2.2 遍歷arr,檢查arr[i]在不在newArr中
            // for (var i = 0; i < arr.length; i++) {
            //     //開關思想 : 某種操作結果只有兩種清空。布林型別儲存兩種情況。
            //     //1.宣告開關
            //     var single = true;//假設不在
            //     //2.遍歷newArr檢查 只要與arr[i]相等
            //     for(var j = 0;j<newArr.length;j++){
            //         if(arr[i] == newArr[j]){
            //             single = false;
            //             break;//只要發現重複元素,後面沒有必要比較
            //         };
            //     };
            //     //3. 根據開關結果實現需求
            //     if(single){
            //         newArr[newArr.length] = arr[i];
            //     };
            // };
    
            // console.log(newArr);
            
    
    
            //3.indexOf : 常用
    
            // //2.1 宣告空陣列儲存去重後的陣列
            // var newArr = [];
            // //2.2 遍歷arr,檢查arr[i]在不在newArr中
            // for (var i = 0; i < arr.length; i++) {
            //     if(newArr.indexOf(arr[i]) == -1){//不在
            //         newArr.push(arr[i]);
            //     }
            // };
    
            // console.log(newArr);
    
            //4.物件法
    
            var arr = [20, 66, 88, 25, 66, 90, 88, 50];
    
            /* 核心思路:利用物件的屬性名不能重複
                物件的取值賦值特點
                    取值 : 存在,取值。 不存在,取undefined
                    賦值 : 存在,修改。 不存在,動態新增
    
            1.宣告空物件 : 檢查陣列元素是否重複 (元素作為屬性名,檢查物件有沒有這個屬性)
            2.宣告空陣列 :儲存去重後的陣列
            3.遍歷arr,檢查arr[i]是否重複
             */
             var obj = {};
             var newArr = [];
             for(var i = 0;i<arr.length;i++){
                //檢查物件有沒有 arr[i] 這個屬性?
                if(obj[arr[i]] == undefined){//未重複 
                    newArr.push(arr[i]);
                    obj[arr[i]] = 1;//這裡賦值目的是為了下一次取值,不是undefined
                }
             };
    
             console.log(newArr);
            
            
            //5.重複元素自我交換刪除法
            /*
            	核心思路:判定元素在陣列中查到的位置是否是自身(元素是一定能找到的)
            		* 如果是自身:說明當前元素還沒有重複
            		* 如果不是自身:說明當前元素在前面已經存在過:交換最後一個元素,然後把最後一個刪除
            		
            	步驟:
            	1.遍歷陣列的每一個元素
            	2.判定當前遍歷的元素在當前陣列中存在的位置,判定位置是否是噹噹前自己的位置
            	2.1.是自己位置,說明前面沒有重複,忽略
            	2.2.不是自己位置,說明前面已經存在:
            		2.2.1交換最後一個元素過來
            		2.2.2然後刪除
            		2.2.3最後一個元素有可能已經與前面重複了,為了不跳過當前新交換的元素,重新從當前元素開始檢索	
            */
            arr = [1,1,2,3,5,0,1];
            for (var i = 0; i < arr.length; i++) {
                //判定當前元素在陣列中找出的位置
                if (arr.indexOf(arr[i]) != i) {
                    //說明不是自己:前面已經存在過
                    //交換最後一個元素過來(因為最後一個可以刪除
                    var temp = arr[i];
                    arr[i] = arr[arr.length - 1];
                    arr[arr.length - 1] = temp;
    			  
                    //刪除最後一個元素:兩種方式都可以
                    // arr.pop();
                    arr.length--;
                    
                    //最後一個元素有可能已經與前面重複了,所以為了保證安全,被交換過來的元素還要重新經受考驗
                    i--;
                }
            }
            
            //注意:以上方式會改變陣列中原來元素的順序位置
    
        </script>
    </body>
    
    </html>
    

    1.2-迴圈巢狀練習:九九乘法表

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <script>
            /*
    第一行 i= 1 ,列數 1 第二行 i= 2 ,列數 2 第三行 i= 3 ,列數 3 ^^^ i = 9 ,列數 9 內層迴圈次數 = i */ //1.外層迴圈 : 行 9 for(let i = 1;i<=9;i++){ //2.內層迴圈次數 = i for(let j = 1;j<=i;j++){// i = 9 j = 1 2 3 4 5 6 7 8 9 document.write(j + '*' + i + '=' + j*i + '&nbsp;&nbsp;'); }; document.write(
    '<br><br>'); }; </script> </body> </html>
  • 1.3-陣列排序-冒泡演算法

演算法algorithm,是一種解決問題的方法

演算法的目標:使用最少的記憶體,最短的時間,解決最多的問題

冒泡演算法:

重複地走訪過要排序的元素列,依次比較兩個相鄰的元素

順序正確:代表位置正確,不需要交換

順序錯誤:交換兩個元素,讓順序正確

<script>
    /*
        冒泡演算法(順序:從小到大)
        1.從第一個元素開始,比較下一個元素
            * 如果前面一個大於後面的元素:交換
            * 如果前面一個小於或者等於後面的元素:不用動
        2.迴圈比較陣列中的每一個元素:直到最大的那個元素到達陣列最後
        
        3.一次迴圈,只能得出最大的資料排到最後,因此需要根據陣列元素的長度來進行迴圈巢狀
            * 一次只能讓當前最大的到最後(如果原來最大的就在最後,那麼就是次大的)
            * 根據陣列長度實現:每次都能得出一個最大,直到全部都排好序
    */
    
    // 定義一個無序陣列
    let arr = [3,5,1,8,6,2];
    
    // 外部迴圈:決定裡面迴圈的次數
    for(let i = 0;i < arr.length;i++){
        // 內部迴圈:決定當前最大的元素跑到正確的位置去
        for(let j = 0;j < arr.length - 1;j++){
            // j < arr.length - 1 是因為需要進行向後一個進行元素匹配
            
            // 判定當前元素與後一個元素的關係:前面大於後面:交換(其他情況不用變)
            if(arr[j] > arr[j+1]){
                // 交換兩個元素的值:採用第三個變數
                let temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    
    console.log(arr);        // [1,2,3,5,6,8]
</script>