FreeCodeCamp 中级算法

本文介绍了几种实用的JavaScript编程技巧,包括求和指定范围内的所有数字、找出两个数组的差集、数字转罗马数字、在对象数组中查找特定属性值以及字符串的查找替换功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、Sum All Numbers in a Range
描述:
我们会传递给你一个包含两个数字的数组。返回这两个数字和它们之间所有数字的和。

最小的数字并非总在最前面。
这是一些对你有帮助的资源:

  • Math.max()
  • Math.min()
  • Math.reduce()
    function sumAll(arr) {
      var _max = Math.max(arr[0], arr[1]);
      var _min = Math.min(arr[0], arr[1]);
      var res = 0;
      while(_max>=_min) {
        res += _min;
        _min++;
      }
      return res;
    }

    sumAll([1, 4]);

还可以这样实现

 function sumAll(arr) {
      var _max = Math.max(arr[0], arr[1]);
      var _min = Math.min(arr[0], arr[1]);
      var arr = [];
      for(var val = _min; val<=_max;val++){
        arr.push(val);  
     }
     return arr.reduce(function(a, b) {
            return a + b
        })
    }

    sumAll([1, 4]);

2、Diff Two Arrays
描述:
比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。换言之,返回两个数组的差异。

这是一些对你有帮助的资源:

slice() 方法返回一个从开始到结束(不包括结束)选择的数组的一部分浅拷贝到一个新数组对象。且原始数组不会被修改。
filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。

function diff(arr1, arr2) {
  var newArr = [];
  newArr = arr1.filter(function(val) {
    return arr2.indexOf(val)==-1;   // 先输出了 4个 false,
  }).concat(arr2.filter(function(val) {
    return arr1.indexOf(val)==-1;   
  }));
    alert(newArr)   // 4 => 4 => pink wool => 1,calf,3,piglet,7,filly 
  return newArr;
}

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

3、Roman Numeral Converter
描述:
将给定的数字转换成罗马数字。

所有返回的 罗马数字 都应该是大写形式。

这是一些对你有帮助的资源:

碰上这题时,我特地去查了罗马数字是怎么回事
1065174-20180406234727261-1977305808.png
看着这张表会发现一些规律,你会发现 数字首个为【1,4,5,9】不同之外,其他都是有规律的。

function convert(num) {
   var decimalValue = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ];
  var romanNumeral = [ 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I' ];
  var romanized = '';
  for(var index = 0; index<decimalValue.length;index++) {
    console.log(index);
    while(decimalValue[index] <= num){
      romanized += romanNumeral[index];
      num -= decimalValue[index];
    }
  }
 return romanized;
}

convert(36);

当实现了之后,感觉不太灵活,于是又搞出了一种写法,按照罗马公式进行计算
1065174-20180407000156308-1599462317.png

function convertToRoman(num) {
 var romans = ["I", "V", "X", "L", "C", "D", "M"],
     ints = [],
     romanNumber = [],
     numeral = "";
  while (num) {
    ints.push(num % 10);
    num = Math.floor(num/10);
  }
  for (i=0; i<ints.length; i++){
      units(ints[i]);
  }
  function units(){
    numeral = romans[i*2];
    switch(ints[i]) {
      case 1:
        romanNumber.push(numeral);
        break;
      case 2:
        romanNumber.push(numeral.concat(numeral));
        break;
      case 3:
        romanNumber.push(numeral.concat(numeral).concat(numeral));
        break;
      case 4:
        romanNumber.push(numeral.concat(romans[(i*2)+1]));
        break;
      case 5:
        romanNumber.push(romans[(i*2)+1]);
        break;
      case 6:
        romanNumber.push(romans[(i*2)+1].concat(numeral));
        break;
      case 7:
        romanNumber.push(romans[(i*2)+1].concat(numeral).concat(numeral));
        break;
      case 8:
        romanNumber.push(romans[(i*2)+1].concat(numeral).concat(numeral).concat(numeral));
        break;
      case 9:
        romanNumber.push(romans[i*2].concat(romans[(i*2)+2]));
      }
    }
  return romanNumber.reverse().join("").toString();
}

convertToRoman(36);

4、Where art thou
写一个 function,它遍历一个对象数组(第一个参数)并返回一个包含相匹配的属性-值对(第二个参数)的所有对象的数组。如果返回的数组中包含 source 对象的属性-值对,那么此对象的每一个属性-值对都必须存在于 collection 的对象中。

例如,如果第一个参数是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }],第二个参数是 { last: "Capulet" },那么你必须从数组(第一个参数)返回其中的第三个对象,因为它包含了作为第二个参数传递的属性-值对。

这是一些对你有帮助的资源:

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)

function where(collection, source) {
  // What's in a name?
  var srcKey = Object.keys(source); // 返回 key 如 last
  return collection.filter(function(obj){
    return srcKey.every(function(key){
        return obj.hasOwnProperty(key) && obj[key] == source[key];
    });
  });
}

where([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });

本代码还涉及到 Array.every() 的资源

5、Search and Replace
使用给定的参数对句子执行一次查找和替换,然后返回新句子。

第一个参数是将要对其执行查找和替换的句子。

第二个参数是将被替换掉的单词(替换前的单词)。

第三个参数用于替换第二个参数(替换后的单词)。

注意:替换时保持原单词的大小写。例如,如果你想用单词 "dog" 替换单词 "Book" ,你应该替换成 "Dog"。

这是一些对你有帮助的资源:

Array.splice()
String.replace()
Array.join()
以下是我实现的

function myReplace(str, before, after) {  
  var str_indexOf = str.indexOf(before);
  if(str[str_indexOf] === str[str_indexOf].toUpperCase()) {
    after = after.charAt(0).toUpperCase() + after.slice(1);
  }
  return str.replace(before, after);
}

myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");

ok,到了这里感觉我实现的是最简单的方式。接下来看看另外两种比较高端的方式:

function myReplace(str, before, after) {
//Create a regular expression object
  var re = new RegExp(before,"gi");
//Check whether the first letter is uppercase or not
  if(/[A-Z]/.test(before[0])){
  //Change the word to be capitalized
    after = after.charAt(0).toUpperCase()+after.slice(1);
     }
     //Replace the original word with new one
  var  newStr =  str.replace(re,after);

 return newStr;
}

// test here
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
function myReplace(str, before, after) {

    // create a function that will change the casing of any number of letter in parameter "target"
    // matching parameter "source"
    function applyCasing(source, target) {
        // split the source and target strings to array of letters
        var targetArr = target.split("");
        var sourceArr = source.split("");
        // iterate through all the items of sourceArr and targetArr arrays till loop hits the end of shortest array
        for (var i = 0; i < Math.min(targetArr.length, sourceArr.length); i++){
            // find out the casing of every letter from sourceArr using regular expression
            // if sourceArr[i] is upper case then convert targetArr[i] to upper case
            if (/[A-Z]/.test(sourceArr[i])) {
                targetArr[i] = targetArr[i].toUpperCase();
            }
            // if sourceArr[i] is not upper case then convert targetArr[i] to lower case
            else targetArr[i] = targetArr[i].toLowerCase();
        }
        // join modified targetArr to string and return
        return (targetArr.join(""));
    }


    // replace "before" with "after" with "before"-casing
    return str.replace(before, applyCasing(before, after));
}

// test here
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");

转载于:https://www.cnblogs.com/johnsken-jerry/p/8729058.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值