js的一些中级算法学习练习
编辑时间:2021-09-28 作者:金满斗 浏览量:1370 来源:原创
范围内的数字求和
我们会传入一个由两个数字组成的数组。 给出一个含有两个数字的数组,我们需要写一个函数,让它返回这两个数字间所有数字(包含这两个数字)的总和。 最低的数字并不总是第一位。
例如,sumAll([4,1]) 应返回 10,因为从 1 到 4(包含 1、4)的所有数字的和是 10。
function sumAll(arr) {
  //注意先排序
   arr.sort((a, b) => a - b);
  //数学求和公式
  //如果能整除,直接加和再乘
  let M = arr[1]-arr[0]+1 ;
  let num = arr[0]+arr[1];
  if(M%2==0){
    return num*M/2;
  }else{
    let n = Math.floor(M/2);
    return num*n+(n+arr[0]);
  }
}

console.log(sumAll([10, 3]));

注意,为什么不用循环,既然是中级算法,就尽量用低级做法,试想如果是从一加到1000W,谁的效率高


数组的对称差
比较两个数组并返回一个新数组,包含所有只在其中一个数组中出现的元素,排除两个数组都存在的元素。 换言之,我们需要返回两个数组的对称差。
例子
function diffArray(arr1, arr2) {
  var newArr = arr1.reduce((
    function(obj,item){
      let index = obj.indexOf(item);
      if(index !=-1){
        obj.splice(index,1);
      }else{
        obj.splice(index,0,item);
      }
      return obj;
    }
  ),arr2);
  return newArr;
}

diffArray([1, 2, 3, 5,9], [1, 2, 3, 4, 5,7]);
这里不用低级循环

过滤数组元素
你将获得一个初始数组(destroyer 函数中的第一个参数),后跟一个或多个参数。 从初始数组中移除所有与后续参数相等的元素。
注意: 你可以使用 arguments 对象。
function destroyer(arr) {
  let removetab = Object.values(arguments).slice(1);
 let rtarr = arr.filter(item=>removetab.indexOf(item)==-1);
  return rtarr;
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);


找出包含特定键值对的对象
创建一个查看对象数组(第一个参数)的函数,并返回具有匹配的名称和值对的所有对象的数组(第二个参数)。 如果要包含在返回的数组中,则源对象的每个名称和值对都必须存在于集合中的对象中。
function whatIsInAName(collection, source) {
   var srcKeys = Object.keys(source);
  return collection.filter(function(obj) {
    return srcKeys.every(function(key) {
      return obj.hasOwnProperty(key) && obj[key] === source[key];
    });
  });
}

whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 })


短线连接格式
将字符串转换为短线连接格式。 短线连接格式是小写单词全部小写并以破折号分隔。
function spinalCase(str) {
  return str.split(/\s|_|(?=[A-Z])/).filter(val => val!="").join('-').toLowerCase();
}

console.log(spinalCase('This Is Spinal Tap'));

搜索与替换
在这道题目中,我们需要写一个字符串的搜索与替换函数,它的返回值为完成替换后的新字符串。
这个函数接收的第一个参数为待替换的句子。第二个参数为句中需要被替换的单词。第三个参数为替换后的单词。
注意: 在更换原始单词时保留原始单词中第一个字符的大小写。 即如果传入的第二个参数为 Book,第三个参数为 dog,那么替换后的结果应为 Dog
function myReplace(str, before, after) {
  if (/^[A-Z]/.test(before)) {
    after = after[0].toUpperCase() + after.substring(1)
  } else {
    after = after[0].toLowerCase() + after.substring(1)
  }
  return str.replace(before, after);
}
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");

DNA 配对
给出的 DNA 链上缺少配对元素。 请基于每个字符,获取与其配对的元素,并将结果作为二维数组返回。
DNA 的碱基对 有两种形式:一种是 A 与 T,一种是 C 与 G。 请为参数中给出的每个字符配对相应的碱基。
注意,参数中给出的字符应作为每个子数组中的第一个元素返回。例如,传入 GCG 时,应返回 [["G", "C"], ["C","G"], ["G", "C"]]。
字符和它的配对组成一个数组中,所有配对数组放在一个数组里。
function pairElement(str) {
 let DNAA={'A':'T','C':'G','T':'A','G':'C'};
 let strarr = str.split('');
 return strarr.reduce((obj,item)=>{
    obj.push([item,DNAA[item]]);
    return obj;
 },[])
}
pairElement("GCG");

寻找缺失的字母
在这道题目中,我们需要写一个函数,找出传入的字符串里缺失的字母并返回它。
如果所有字母都在传入的字符串范围内,返回 undefined。
function fearNotLetter(str) {
    let star = str.charCodeAt(0);
    let currt="";
    str.split("").every(function(v, i){ 
    currt = String.fromCharCode(star + i); 
    return currt === v; 
    }); 
    return currt === str[str.length-1] ? undefined : currt; 
}
fearNotLetter("abce");

集合排序通过
编写一个带有两个或更多数组的函数,并按原始提供的数组的顺序返回一个新的唯一值数组。换句话说,所有数组中出现的所有值都应按其原始顺序包括在内,但最终数组中不得重复。去重后的数字应按其出现在参数中的原始顺序排序,最终数组不应按数字大小进行排序。
例子:
function uniteUnique(arr) {
  let removetab = [...arguments];
  let narr = removetab.reduce((obj,item)=> obj.concat(item),[]);
  let newobj = narr.reduce(
    (obj,item)=> {
      if(obj.indexOf(item)==-1){
          obj.push(item)
       }
      return obj; },[]);
  return newobj ;
}
转换 HTML 字符实体,请将字符串中的 &、<、>、"(双引号)和 '(单引号)转换为相应的 HTML 字符实体。
例子:
function convertHTML(str) {
  const htmlEntities = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&apos;"
  };
  return str.replace(/([&<>\"'])/g, match => htmlEntities[match]);
}
convertHTML("Dolce & Gabbana");

uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);

求斐波那契数列中的奇数之和
例子:
function sumFibs(num) {
   var pre = 0;
    var cur = 1;
    var arr=[];
    while (cur <= num) {
        if (cur % 2 !== 0) {
            arr.push(cur);
        }
        cur += pre;
        pre = cur - pre;
    }
    return arr.reduce((x,y)=>x+y);
}
sumFibs(4);

质数求和
质数(prime number)是大于 1 且仅可以被 1 和自己整除的数。 比如,2 就是一个质数,因为它只可以被 1 和 2(它本身)整除。 相反,4 不是质数,因为它可以被 1, 2 和 4 整除。
请完成 sumPrimes 方法,使其返回小于等于传入参数数字的所有质数之和。
function sumPrimes(num) {
  let primes = [];
  for (let i = 2; i <= num; i++) {
    if (primes.every((prime) => i % prime !== 0))
      primes.push(i);
  }
  return primes.reduce((sum, prime) => sum + prime, 0);
}
sumPrimes(10);

找出数字范围内的最小公倍数
找到给定参数的最小公倍数,可以被这两个参数整除,也可以被指定范围内的所以整数整除。
注意,较小数不一定总是出现在数组的第一个元素。
例如,如果给定 1 和 3,找到 1 和 3 的最小公倍数,也可以被 1 到 3 之间的所有数字整除。 这里的答案将是 6。
function smallestCommons(arr) {
  const [min, max] = arr.sort((a, b) => a - b);
  const range = Array(max - min + 1)
    .fill(0).map((_, i) => i + min);
  const gcd = (a, b) => (b === 0) ? a : gcd(b, a % b);
  const lcm = (a, b) => a * b / gcd(a, b);
  return range.reduce((multiple, curr) => lcm(multiple, curr));
}
smallestCommons([1,5]);

根据参数删除数组元素
给定数组 arr,从数组的第一个元素开始,用函数 func 来检查数组的每个元素是否返回 true。 如果返回 false,就把这个元素删除。 持续执行删除操作,直到某个元素传入 func 时返回 true 为止。
然后在条件满足后返回数组的其余部分,否则, arr 应作为空数组返回。
例子
function dropElements(arr, func) {
  let retarr = [];
  for(let i=0;i<arr.length;i++){
    if(func(arr[i])){
       retarr = arr.splice(i,arr.length);
      break;
      }
  }
  return retarr;
}

dropElements([1, 2, 3, 9, 2], function(n) {return n > 2; });

数组扁平化
嵌套数组扁平化成一维数组。 必须考虑到各种深度的嵌套层级。
function steamrollArray(arr) {
  const flat = [].concat(...arr);
  return flat.some(Array.isArray) ? steamrollArray(flat) : flat;
}

steamrollArray([1, [2], [3, [[4]]]]);

翻译二进制字符串
请实现一个函数,把传入的二进制字符串转换成英文句子。
二进制字符串会以空格分隔。
function binaryAgent(str) {
  return String.fromCharCode(
    ...str.split(" ").map(char=> parseInt(char, 2)
    )
  );
}

binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 001111111010101");

来说两句吧