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

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 lists
var 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值