首页 > 代码库 > Freecodecamp 高级算法(个人向)

Freecodecamp 高级算法(个人向)

freecodecamp 高级算法地址戳这里。

freecodecamp的初级和中级算法,基本给个思路就能完成,而高级算法稍微麻烦了一点,所以我会把自己的解答思路写清楚,如果有错误或者更好的解法,欢迎留言。

Validate US Telephone Numbers

如果传入字符串是一个有效的美国电话号码,则返回 true.

技术分享

简单来说,美国号码的规则就是,国家代码(必须为1),然后就是3,3,4的数字组合,前三个数字可以用括号包起来。另外就是间隔使用空格或者“-”。

因为输入值肯定是字符串,规则也较多,所以考虑用正则做。

先贴代码:

function telephoneCheck(str) {
  // Good luck!
  var reg=/^(1\s?)?\(?\d{3}\)?(\s|-)?\d{3}(\s|-)?\d{4}/;   //正则规则
  
  var index1=str.indexOf("(");   
  var index2=str.indexOf(")");   //查询到两个括号
  
  if( (index1!=-1 && index2!=-1) || (index1==-1 && index2==-1) ){   //存在双括号或者没有括号
    if( index2!=index1 && index2-index1!=4 ){  //如果存在双括号,且序号间的字符有3个
      return false;
    }
    var str2=str.replace(/[\(\)\s-]/g,"");  //将括号和空格和“-”全局替换成空,便于统计数字长度
    if( str2.length==11 && str2.substr(0,1)!=1 ){
      return false;
    }
          
  }else{ 
      return false; 
  }
    
  return reg.test(str);  
}

telephoneCheck("27576227382");

当首次尝试直接匹配号码的时候我们发现不行,因为我们没办法同时匹配到双括号,正则规则存在一些盲点,这些盲点首先就是双括号的问题,再有就是长度问题,对于超出长度的字符我们没有匹配验证的能力,这就需要我们用js进行一些弥补。

我的做法,首先验证是否有双括号,同时有或者同时没有皆可;如果只有一个,返回false。接着在同时有或者同时没有双括号里面追加两个判断,如果有双括号,那么两个括号之间的字符一定是三个,否则返回false,如果确实返回3个,那我们也不用进行过多的判断,因为正则里已经写好了。接着就是通过replace将一切干扰元素去掉,验证一下字符串的长度有没有超出11;当长度为11时,第一个数字是不是1。完成了这些用来完善的判断,最后进行一下正则的匹配就可以了。

Symmetric Difference

创建一个函数,接受两个或多个数组,返回所给数组的 对等差分(symmetric difference) ( or )数组

输入的数组可能会是多个,而题目的要求是按顺序两两处理。也就是说,我们把前两个数组各自独有的元素组成新数组后,再和第三个数组进行处理,以此类推,最终会返回一个数组。这种模式让我们想到了数组的reduce方法,前两个处理出一个结果,处理出的结果再和下一个进行处理,直到最后得到一个结果。

所以主体函数的最后只要使用reduce就可以了,那么目前的问题就是解决两个数组之间如何消去所有的相同元素,然后返回一个排好序的新数组。因为一个数组当中都可能存在重复的元素,如果只是两个数组都删除相同的,可能还会删不干净。

我的思路是这样的,既然我们的目标只有值,而不在乎数量,所以一个开始就可以对两个数组分别进行一次去重,然后就是两个删除一个相同元素然后拼接排序。我这里呢,偷了个懒,用的还是去重的函数,等于省了一个函数。

function sym(args) {
  var arrs=[];
  for(var a of arguments){
    arrs.push(a);
  }
  var res=arrs.reduce(function(a,b){  
    a=del(a);
    b=del(b);  //数组分别处理
    var arr=a.concat(b);   
    return del(arr,true);  //拼接成一个大数组后,再进行一次处理
  });
  
 return res;
}
 
function del(arr,flag){   //排序and去重   flag为true表示删干净,否则留一个
  var start,end;    
  arr.sort(function(a,b){  //数组由小到大排序
    return a-b;
  });
  for(var i=0;i<arr.length;i++){
    if(arr[i]==arr[i+1]){  //发现重复
      start=(start===undefined)?i:start;  //start为重复的起始位置
      end=i+1;           //end为重复的结束位置
    }else{   
      if( end && end==i ){  //如果存在重复,即end有值,按照flag对数组进行处理。
        if( flag ){
          arr.splice(start,end-start+1);
          i=i-(end-start+1);
        }else{
          arr.splice(start,end-start);
          i=i-(end-start);
        }
        start=undefined;  //没有重复了,start要还原
      }      
    }
  }
  
  return arr;
  
}
sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);

 

未完待续。。。

 

Freecodecamp 高级算法(个人向)