Advanced Algorithm Scripting (50 hours)Javascript进阶算法练习

来源:互联网 发布:仙侣情缘手游java 编辑:程序博客网 时间:2024/06/09 17:02

1.Validate US Telephone Numbers验证美国电话号码

用户可以在表单中填入一个任意有效美国电话号码. 下面是一些有效号码的例子(还有下面测试时用到的一些变体写法):
555-555-5555
(555)555-5555
(555) 555-5555
555 555 5555
5555555555
1 555 555 5555
在本节中你会看见如 800-692-7753 or 8oo-six427676;laskdjf这样的字符串. 你的任务就是验证前面给出的字符串是否是有效的美国电话号码. 区号是必须有的. 如果字符串中给出了国家代码, 你必须验证其是 1. 如果号码有效就返回 true ; 否则返回 false
telephoneCheck(“1(555)555-5555”) 应该返回 true.
telephoneCheck(“1 555)555-5555”) 应该返回 false.

  // Good luck!  //11个号码,验证第一个是否是1  //10个号码,如果有括号,则是两个,且必须有-  //-1会被看成"-" 和"1"如何解决?:第一个字符为符号,则return false  var newStr='';  var count=0;  var strNum=[];  var strStr=[];  newStr=str.split(" ");  newStr=newStr.join("");  newStr=newStr.split("");//取出空格,因为""%1==0;  if(newStr[0]=="-"){    return false;  }  for(i=0;i<newStr.length;i++){    if(newStr[i]%1===0){//如果为数字;用%来区分数字      count++;      strNum.push(newStr[i]);//所有数字存进去    }else{      strStr.push(newStr[i]);//所有符号存进去    }  }  console.log(count);  if(count<10 || count>11){//号码个数不对    return false;  }  if(count==11){    if(strNum[0]!=="1"){      return false;    }else if(strNum[0]=="1"){    if(strStr.indexOf("(")!==-1 && strStr.indexOf(")")!==-1 && strStr.indexOf("-")!==-1){//三个都有        return true;      }else if(strStr.indexOf("(")==-1 && strStr.indexOf(")")==-1 && strStr.indexOf("-")!==-1){//只有-        return true;      }else if(strStr.indexOf("(")==-1 && strStr.indexOf(")")==-1 && strStr.indexOf("-")==-1){//三个都没有        return true;      }else{        return false;      }    }  }  if(count==10){          if(strStr.indexOf("(")!==-1 && strStr.indexOf(")")!==-1 && strStr.indexOf("-")!==-1){//三个都有        return true;      }else if(strStr.indexOf("(")==-1 && strStr.indexOf(")")==-1 && strStr.indexOf("-")!==-1){//只有-        return true;      }else if(strStr.indexOf("(")==-1 && strStr.indexOf(")")==-1 && strStr.indexOf("-")==-1){//三个都没有        return true;      }else{        return false;      }  }}

2.Symmetric Difference对等差分

创建一个函数,接受两个或多个数组,返回所给数组的 对等差分(symmetric difference) (△ or ⊕)数组.
给出两个集合 (如集合 A = {1, 2, 3} 和集合 B = {2, 3, 4}), 而数学术语 “对等差分” 的集合就是指由所有只在两个集合其中之一的元素组成的集合(A △ B = C = {1, 4}). 对于传入的额外集合 (如 D = {2, 3}), 你应该安装前面原则求前两个集合的结果与新集合的对等差分集合 (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4}).
sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]) 应该返回 [1, 4, 5];
sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]) 应该返回 [2, 3, 4, 6, 7].

function sym(args) {  //解法:直接把所有数字列出来,个数为奇数的组成一个新的数列,就这么简单。  var arr=[];  var count=0;  var results=[];  var deleteC=0;  //去重1:sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);,每个数组内保证没有相同的元素  for(i=0;i<arguments.length;i++){    for(j=0;j<arguments[i].length;j++){      for(k=0;k<arguments[i].length;k++){        if(arguments[i][j]==arguments[i][k]){          deleteC++;        }      }      if(deleteC>=2){        arguments[i].splice(j,1);        k--;      }            deleteC=0;    }  }  //数字全放进一个数组arr里:  for(i=0;i<arguments.length;i++){    for(j=0;j<arguments[i].length;j++){      arr.push(arguments[i][j]);    }  }  //计算个数,保留偶数个的项,用indexOf来判断是否已有这个数  for(i=0;i<arr.length;i++){    for(j=0;j<arr.length;j++){      if(arr[i]==arr[j]){        count++;      }    }    if(count%2!==0){//为奇数      if(results.indexOf(arr[i])==-1){//没有这个数的话才加进去      results.push(arr[i]);    }    }    count=0;  }  return results;}

3.Exact Change零钱找补

设计一个收银程序 checkCashRegister() ,其把购买价格(price)作为第一个参数 , 付款金额 (cash)作为第二个参数, 和收银机中零钱 (cid) 作为第三个参数.
cid 是一个二维数组,存着当前可用的找零.
checkCashRegister(3.26, 100.00, [[“PENNY”, 1.01], [“NICKEL”, 2.05], [“DIME”, 3.10], [“QUARTER”, 4.25], [“ONE”, 90.00], [“FIVE”, 55.00], [“TEN”, 20.00], [“TWENTY”, 60.00], [“ONE HUNDRED”, 100.00]]) 应该返回 [[“TWENTY”, 60.00], [“TEN”, 20.00], [“FIVE”, 15], [“ONE”, 1], [“QUARTER”, 0.50], [“DIME”, 0.20], [“PENNY”, 0.04]].

function checkCashRegister(price, cash, cid) {  var change=[];  var cidSum=0;//零钱总值  var cidArr=[0.01,0.05,0.1,0.5,1,5,10,20,100];  var num=[];//单位零钱个数,倒着的  var value=cash-price;  //所有零钱加起来,刚好等于cash-price,则closed,小于的话或者零钱数不合适就insufficient funds,  for(i=0;i<cid.length;i++){//倒着来    cidSum=cidSum+cid[i][1];    num.push(cid[i][1]/cidArr[i]);  }  //零钱的单位值列出来一个数列:  if(value==cidSum){    return "Closed";  } else if(value>cidSum){    return "Insufficient Funds";  }  if(value<cidSum){//小于总值    for(i=cid.length-1;i>=0;i--){//倒着判断//i为>=0      if(value>=cidArr[i] && value>=cid[i][1] && cid[i][1]!==0){//大于单位值并且大于单位总值,且总值不为0        change.push(cid[i]);        value=value-cid[i][1];      }else if(value>=cidArr[i] && value<cid[i][1]){//大于单位值,小于总值,加上单位值的整数倍        for(j=1;j<num[i];j++){// 最后的0.4会变成0.03999999999999487          if(value>=j*cidArr[i]-0.00006&& value<(j+1)*cidArr[i]-0.00006){//0.04 最后出来的是0.03;进行误差修复              //console.log(0.03999999999999487>=3*0.01-0.00006&&0.03999999999999487<4*0.01);            cid[i][1]=j*cidArr[i];            change.push(cid[i]);            value=value-cid[i][1];   }}}}}  if(value>0.1){//误差判断          return "Insufficient Funds";}  return change;}

4.Inventory Update

依照一个存着新进货物的二维数组,更新存着现有库存(在 arr1 中)的二维数组. 如果货物已存在则更新数量 . 如果没有对应货物则把其加入到数组中,更新最新的数量. 返回当前的库存数组,且按货物名称的字母顺序排列.
updateInventory([], [[2, “Hair Pin”], [3, “Half-Eaten Apple”], [67, “Bowling Ball”], [7, “Toothpaste”]]) 应该返回 [[67, “Bowling Ball”], [2, “Hair Pin”], [3, “Half-Eaten Apple”], [7, “Toothpaste”]].

function updateInventory(arr1, arr2) {    // 判断是否有,有,数字加起来;没有,就push,最后把首字母转化为数字,再顺序排序  var num1=[];  var str1=[];  var num2=[];  var str2=[];  var sortNumber1;  var sortNumber2;  for(i=0;i<arr1.length;i++){    num1.push(arr1[i][0]);    str1.push(arr1[i][1]);  }  for(i=0;i<arr2.length;i++){    num2.push(arr2[i][0]);    str2.push(arr2[i][1]);  }  for(i=0;i<str2.length;i++){    if(str1.indexOf(str2[i])!==-1 ){      sortNumber1=str1.indexOf(str2[i]);      sortNumber2=str2.indexOf(str2[i]);      arr1[sortNumber1][0]+=num2[sortNumber2];    }else{      arr1.push(arr2[i]);    }  }  //下面进行字母顺序排序:  var count=0;  var exchange;  var a,c;  var b,d;  var results=[];  for(i=0;i<arr1.length;i++){    for(j=0;j<arr1.length;j++){       a=arr1[i][1].charCodeAt(0);       b=arr1[j][1].charCodeAt(0);      if(a==b && arr1[i][1]!==arr1[j][1]){//如果首字母相同且不是它本身       for(k=1;k<arr1[i][1].length;k++){         c=arr1[i][1].charCodeAt(k);         d=arr1[j][1].charCodeAt(k);        // console.log(c);         //console.log(d);             if(c>d){           count++;           break;         }         if(c<d){           break;         }       }      }      if(a>b){        count++;      }//位置交换  }     results[count]=arr1[i];      count=0;}    return results;}// Example inventory listsvar curInv = [    [5, "Microphone"],    [21, "Bowling Ball"],    [2, "Dirty Sock"],    [1, "Hair Pin"]];var newInv = [    [2, "Hair Pin"],    [67, "Bowling Ball"],    [7, "Toothpaste"]];

4.No repeats please 数组全排序

把一个字符串中的字符重新排列生成新的字符串,返回新生成的字符串里没有连续重复字符的字符串个数.连续重复只以单个字符为准
例如, aab 应该返回 2 因为它总共有6中排列 (aab, aab, aba, aba, baa, baa), 但是只有两个 (aba and aba)没有连续重复的字符 (在本例中是 a).

function permAlone(str) {  //Heap's algorithm全排列算法  //: re=/(.)\1+/g;   var arr=str.split("");  var re=/(.)\1+/g;  var permutations=[];  var exchange;  //交换  function swap(index1,index2){    exchange=arr[index2];    arr[index2]=arr[index1];    arr[index1]=exchange;  }  //迭代生成全数列  function generate(int){    if(int === 1){      permutations.push(arr.join(""));    }else {      for(var i = 0; i != int; ++i){        generate(int -1);        swap(int % 2 ? 0: i,int-1);//int为偶数,则从i开始,为奇数,从0开始      }    }  }  generate(arr.length);  var filtered=permutations.filter(function(string){    return !string.match(re);  });  return filtered.length;}

5.Friendly Date Ranges 让日期区间更友好!

把常见的日期格式如:YYYY-MM-DD 转换成一种更易读的格式。
易读格式应该是用月份名称代替月份数字,用序数词代替数字来表示天 (1st 代替 1).
记住不要显示那些可以被推测出来的信息: 如果一个日期区间里结束日期与开始日期相差小于一年,则结束日期就不用写年份了。月份开始和结束日期如果在同一个月,则结束日期月份就不用写了。
另外, 如果开始日期年份是当前年份,且结束日期与开始日期小于一年,则开始日期的年份也不用写。
例如:
makeFriendlyDates([“2016-07-01”, “2016-07-04”]) 应该返回 [“July 1st”,”4th”]
makeFriendlyDates([“2016-07-01”, “2018-07-04”]) 应该返回 [“July 1st, 2016”, “July 4th, 2018”].

function makeFriendlyDates(arr) {  //取出月份,变成英文,  //年份相减判断是否要加年份  //当前年份是2016,  for(i=0;i<arr.length;i++){    arr[i]=arr[i].split("-");    for(j=1;j<3;j++){ //只改月份    arr[i][j]=parseInt(arr[i][j],10);    }}    var change=arr;    var arr1=change[0];    var arr2=change[1];    var diff=parseInt((arr2[0]-arr1[0]),10)*365+parseInt((arr2[1]-arr1[1]),10)*30+parseInt((arr2[2]-arr1[2]),10);  for(i=0;i<arr.length;i++){    if(arr[i][2]==1){      arr[i][2]=arr[i][2]+"st";    }else if(arr[i][2]==2){      arr[i][2]=arr[i][2]+"nd";    }else if(arr[i][2]==3){      arr[i][2]=arr[i][2]+"rd";    }    else {    arr[i][2]=arr[i][2]+"th";    }    }  var months=["occupied","January","February","March","April","May","June","July","August","September","October","November","December"];  var result=[];  if(diff<365){//相差不足一年:结束不写    if(parseInt(arr1[0],10)==2016){//开始日期为2016:开始不写       if(arr1[1]==arr2[1]){//同月份:结束月份不写         result[0]=months[arr1[1]]+" "+arr1[2];         result[1]=arr2[2];       }else {//不同月份         result[0]=months[arr1[1]]+" "+arr1[2];         result[1]=months[arr2[1]]+" "+arr2[2];                }       }    else {//no 2016 begins       if(arr1[1]==arr2[1]){//同月份:结束月份不写         if(arr1[2]==arr2[2] &&arr1[0]==arr2[0]){           result[0]=months[arr1[1]]+" "+arr1[2]+", "+arr1[0];         }else if( arr1[0]!==arr2[0]){         result[0]=months[arr1[1]]+" "+arr1[2]+", "+arr1[0];         result[1]=months[arr2[1]]+" "+arr2[2];                     }         else {         result[0]=months[arr1[1]]+" "+arr1[2]+", "+arr1[0];         result[1]=arr2[2];}       }else {//不同月份         result[0]=months[arr1[1]]+" "+arr1[2]+", "+arr1[0];         result[1]=months[arr2[1]]+" "+arr2[2];                }          }  }else{//diff>=365         result[0]=months[arr1[1]]+" "+arr1[2]+", "+arr1[0];         result[1]=months[arr2[1]]+" "+arr2[2]+", "+arr2[0];     }  return result;}

6.Make a Person 用下面给定的方法构造一个对象.

方法有 getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).

var Person = function() {  //有6个方法  var x=arguments[0];//全名字符串  var y=x.split(" ");//全名数组    this.getFirstName=function(){      return y[0];    };    this.getLastName=function(){      return y[1];    };  this.getFullName=function(){      return y[0]+" "+y[1];    };  this.setFirstName=function(item){      y[0]=item;    };  this.setLastName=function(item){      y[1]=item;    };  this.setFullName=function(item){      item=item.split(" ");      y[0]=item[0];      y[1]=item[1];    };    //return firstAndLast;};

7.Map the Debris返回一个数组,其内容是把原数组中对应元素的平均海拔转换成其对应的轨道周期

orbitalPeriod([{name: “iss”, avgAlt: 413.6}, {name: “hubble”, avgAlt: 556.7}, {name: “moon”, avgAlt: 378632.553}]) 应该返回 [{name : “iss”, orbitalPeriod: 5557}, {name: “hubble”, orbitalPeriod: 5734}, {name: “moon”, orbitalPeriod: 2377399}].

function orbitalPeriod(arr) {  var GM = 398600.4418;  var earthRadius = 6367.4447;  for(i=0;i<arr.length;i++){    var a = arr[i].avgAlt+earthRadius;    delete arr[i].avgAlt;    var result = 2*Math.PI*Math.pow(a*a*a/GM,1/2);    result=Math.round(result);    arr[i].orbitalPeriod=result;  }  return arr;}

8.Pairwise,配对

举个例子:有一个能力数组[7,9,11,13,15],按照最佳组合值为20来计算,只有7+13和9+11两种组合。而7在数组的索引为0,13在数组的索引为3,9在数组的索引为1,11在数组的索引为2。
所以我们说函数:pairwise([7,9,11,13,15],20) 的返回值应该是0+3+1+2的和,即6。

function pairwise(arr, arg) {  var result=0;  for(i=0;i<arr.length;i++){    for(j=i+1;j<arr.length;j++){      if(arr[i]+arr[j]==arg){        result=result+i+j;        arr.splice(i,1,NaN);        arr.splice(j,1,NaN);        console.log(arr);      }    }  }  return result;}
0 0
原创粉丝点击