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]);
未完待续。。。