鸿蒙-JS-第二周day02

一、算法之数组去重

方法一:

【简单思路实现】:依次拿出数组的中的每一项,和后面的所有项进行比较,如果有相同的就删除。

var ary=[1,2,3,2,4];
/* 
思路:
第一次:
   拿出数组的第一项:1
                 给[2,3,2,4]进行比较,如果有重复就删除
   拿出数组的第二项:2   
                   ====[3,2,4]进行比较,有重复的删除 [3,4]  
   拿出数组的第三项:3
                   ===4 进行比较,有重复的删除,没有重复
   还用拿最后一项4吗?====不用了                                     
依次拿出数组中的每一项给剩余的所有项进行比较

*/
function unique(ary){
    for(var i=0;i<ary.length-1;i++){
        var getItem=ary[i];
        for(var j=i+1;j<ary.length;j++){
           var remainItem=ary[j];
           // 如果当前项和后面的项在进行比较的时候,相同就说明重复,要删除掉原数组的那项
           if(getItem==remainItem){
              ary.splice(j,1);
              j--;
           }
        }
   }
   return ary;
}

console.log(unique(ary));

【splice造成的数组塌陷问题】

var ary=[1,2,1,3,3,2,3];


for(var i=0;i<ary.length-1;i++){
    var current=ary[i];
    for(var j=i+1;j<ary.length;j++){
         var next=ary[j];
         if(current==next){
            ary.splice(j,1);
            j--;
         }
    }
}

console.log(ary)

方法二:

【实现的思路】利用对象属性名不重复的思想,先建立一个空对象,然后依次循环数组中的每一项,把此项作为obj对象的属性名和属性值,在添加的时候,如果这个属性名对应的值已经存在,说明此项重复,删除掉此项

/* 
var ary2=[1,2,1,3,3,2,3];

利用对象属性名不能重复的原理:对象中如果没有一个属性的时候就是undefined
把数组中的每一项作为一个对象的属性名和属性值
var obj={1:1,2:2,3:3} 
原理:如果对象属性中已经存在这个属性名,我们就把原数组中此项进行删除
*/
function unique(ary){
   var obj={};
   for(var i=0;i<ary.length;i++){
       var item=ary[i];
       if(typeof (obj[item])!="undefined"){
         //如果此时对象的此属性已经有了,我们就应该删除数组中的那一项
         ary.splice(i,1);
         i--;
         continue;
       }
       obj[item]=item;
   }
   return ary;
}

var ary2=[1,2,1,3,3,2,3];
var res=unique(ary2);
console.log(res);

【优化方法】:对于数组塌陷,数组中后面所有的数字都要依次改变,这样比较耗性能,怎么优化呢?可以让后面的索引值不变,这样就可以省性能。

  • 把最后一项的值拿过来,占位到塌陷的此项
  • 把最后一项删除
  • 需要注意,此时最后一项也需要比较所以还需要i--;

var ary=[1,2,3,2,3];
var obj={};

for(var i=0;i<ary.length;i++){
   var item=ary[i];
   if(typeof obj[item]!=="undefined"){
        // 把当前重复的项替换成最后一项
        ary[i]=ary[ary.length-1];
        // 最后一项都已经拿过来了,多余,所以删除掉
        ary.length--;
        // 此时占位的这一项(最后一项)还没有比较,所以需要i--,再重新比较一次
        i--;
        continue;
   }
   obj[item]=item;
}

console.log(ary);

方法三:indexOf

创建一个新数组,遍历原数组,如果新数组中没有那一项的话,就把它push进去

/* 
  var ary2=[1,2,1,3,3,2,3];
  var newAry=[];
  把原数组中的每一项,只要在新数组中没存在过,我们就把它放进去,最后newAry就是咱们最终要的数组
*/

function unique(ary){
   var newAry=[];
   for(var i=0;i<ary.length;i++){
       var item=ary[i];
       if(newAry.indexOf(item)==-1){
        newAry.push(item);
       }
   }
   return newAry;
}
var ary2=[1,2,1,3,3,2,3];
var res=unique(ary2);
console.log(res);

二、算法之冒泡排序

   /* 
   冒泡排序:
   从小到大排序
   var ary=[8,5,1,2]
   原理:依次拿出数组中的每一项给后面的一项做对比,如果当前项比后面的项大就交换位置
   第一轮:[5,1,2,8] 经过一轮比较出现了最大数
   第二轮:[2,1,5,8] 经过二轮比较得出倒数第2个数
   第三轮:[1,2,5,8]  经过二轮比较得出倒数第3个数
   .... 总共四项,经过比三轮,已经得到了三个最大数了,最后一个自然就是最小数
   【需要比的总轮数】:ary.length-1;
   【每次需要比的次数】:ary.length-1-已经比较过的轮数

   第一轮:4项两两比较需要比3次:ary.length-1
   第二轮: 正常的ary.length-1-已经比较过的轮数
   
   */

   function sort(ary){
       // 需要比较的轮数
       for(var i=0;i<ary.length-1;i++){
           for(var j=0;j<ary.length-1-i;j++){
              var current=ary[j];
              var next=ary[j+1];
              if(ary[j]>ary[j+1]){
                 // 让 ary[j]=ary[j+1]
                 var temp=ary[j]
                 ary[j]=ary[j+1];
                 ary[j+1]=temp;
                    
              }
           }
       }
       return ary;
   }

   var ary=[8,5,1,2];
   var res=sort(ary);

三、递归

自己调自己就是递归;

function fn(num){
  fn(num-1)
}
fn(10)

打印1 到10

// 打印1到10

function fn(num){
    if(num>10){
         return 
    }
    console.log(num); 
    fn(num+1);  
}
fn(1)

[练习题]:求一个1到100的所有数之和

答案一:


/* 
  1到100中所有数之和
*/
function total(star,end){
    var total=0;
    for(var i=star;i<=end;i++){
        total+=i;
    }
    return total;
}
var res=total(1,100);
console.log(res);

答案二:递归

function total(num){
   if(num>100){
     return 0;
   }
   return num+total(num+1);
}
total(1)

[练习题]:求1到100中同时能被2整除又能被3整除的所有数之和

答案:1

/* 
求1-100所有能被2整除又能被3整除的所有数之和
*/
var total=0;
for(var i=1;i<=100;i++){
    
   if(i%2==0&&i%3==0){
      total+=i;
   }
}
console.log(total);

递归

function total(num){
   if(num>100){
     return 0;
   }
   if(num%2==0&&num%3==0){
    return  num+total(num+1);
   }
   return total(num+1);
}
var res=total(1);

四、算法之快速排序

/* 
 快速排序
 var ary=[12,15,14,13,16,11];
 原理:先拿出中间项,然后把此项从数组中删除掉,让数组中的剩余项一一跟这个中间项做比较,新建两个左右数组,如果大的项就放到右盒子,如果小的项就放到左盒子
 [左盒子小]--中间项--[右盒子大]
 依次再继续重复相同的步骤,把左盒子和右盒子都进行排序,直到出现空数组或者一项的时候停止
*/
function quickSort(ary){
    if(ary.length<=1){
        return ary;
    }
   var centerIndex=Math.floor(ary.length/2);
   // 拿到中间项的同时,把中间项从数组中删除掉
   var centerValue=ary.splice(centerIndex,1)[0];
   // 新建两个数组:leftAry,rightAry;把ary中剩余的项,给中间项做对比,如果大项就放到右数组,小项就放到左数组.
   var leftAry=[],rightAry=[];
   for(var i=0;i<ary.length;i++){
        if(ary[i]<centerValue){
            leftAry.push(ary[i]);
        }else{
            rightAry.push(ary[i]);
        }
    }
    return quickSort(leftAry).concat(centerValue,quickSort(rightAry));
}
var ary=[12,15,14,13,16,11];
var res=quickSort(ary);

五、插入排序

/* 
var ary=[34,56,12,66,12];
插入排序:
新建一个数组:依次拿出原数组中的每一项往新数组里面插入,插入的时候需要遵循一个规律:
               1)方向:从右向左
               2)最终实现的效果,从小到大,在插入的时候,拿出的项
               从右向左依次比较(新数组),如果拿出的项大(或者相等),就直接插入首次比它小的后面,
               3)如果一直比到第一项了,条件还没满足,后面就是最小项,直接放到数组的最前面
var newAry=[]
第一次====>我拿出第一项直接放进去,不用进行比较
           newAry=[34]
第二次====> 拿出56 [34,56]          

第三次====> 拿出12 [12,34,56]

第四次=====> 拿出66 [12,34,56,66]

第五次=====> 拿出12 [12,12,34,56,66]
*/
var ary=[34,56,12,66,12];
function insertSort(ary){
   //最终排序好的数组盒子
   var newAry=[];
   //拿出的第一项放进去,此时盒子中只有一项,不用个比较
   newAry.push(ary[0]);
   // 依次拿出原数组中的每一项进行插入
   for(var i=1;i<ary.length;i++){
      var getItem=ary[i];
      // 在插入的时候需要跟新数组中的每一项进行比较(从右向左)
      for(var j=newAry.length-1;j>=0;j--){
           var newItemAry=newAry[j];
           if(getItem>=newItemAry){
             // 如果拿出的项比某项大或者相等,就放到此项的后面
             newAry.splice(j+1,0,getItem);
             // 插入完毕,不用再继续比较停止循环;
             break;
           }
           if(j==0){
            //如果都已经比到第一项了,还没满足条件,说明这个就是最小项,我们之间插入到数组的最前面
            newAry.unshift(getItem);
           }
      }

   }
   return newAry;
}
var res=insertSort(ary)

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值