题目链接:https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting

1. Sum All Numbers in a Range


传入的参数是包含两个数字的数组,要求计算两数之间(包含边界)所有数字的和,较小的数字不一定在数组第一位;

function sumAll(arr) {
var start = arr[0]
,end = arr[1];
return (start + end) * (Math.abs(end - start) + 1) / 2;
} sumAll([1, 5]); // 15

2. Diff Two Arrays


传入两个数组,要求求差,即返回一个新数组,新数组里的值只能在数组1或数组2中找到,不能同时出现在两个数组中;

function diffArray(arr1, arr2) {
arr1 = arr1.slice(); // 为了不改变传入的数组的值,先对数组进行一次浅复制
arr2 = arr2.slice();
for (var i = arr1.length - 1; i >= 0; i--) {
var index = arr2.indexOf(arr1[i]); // 寻找两个数组同时拥有的项,找到的话把这一项从两个数组中删掉
if (index > -1) { // 必须先把index存起来,因为后面使用splice()会改变数组,这时再动态查询index计算会出错误
arr1.splice(i, 1); // arr1去掉了一项,后面一项往前移,此时再用arr2.indexOf(arr1[i])得到的结果就是错的了
arr2.splice(index, 1);
}
}
var newArr = arr1.concat(arr2); // 剩下来的就是两个数组中不同的值
return newArr;
}

也可以先把两个数组合并起来,再使用类似数组去重的方法,但是找到的相同元素不是留一个,而是要全删掉;

function diffArray(arr1, arr2) {
var newArr = arr1.concat(arr2);
var re = [];
newArr.forEach(ele => {
var index = re.indexOf(ele); // 这里的index不用先保存也不会出错
if (index === -1) { // 如果结果数组中没有,就把这一项加进去
re.push(ele);
} else { // 如果在结果数组中已存在,那就忽略这一项,并把在结果数组中存在的这一项也删掉,这里和数组去重不一样
re.splice(index, 1);
}
});
return re;
}

3. Seek and Destroy


传入一个数组和若干个其他参数,要求删除数组中与其他参数相等的项;

function destroyer(arr) {
var removedVal = Array.prototype.slice.call(arguments, 1);
var re = arr.filter(ele => removedVal.indexOf(ele) === -1);
return re;
} destroyer([1, 2, 3, 1, 2, 3], 2, 3); // [1, 1]

4. Wherefore art thou


写一个函数,这个函数接收两个参数,第一个参数是成员都是对象的数组,第二个参数是一个对象;

要求遍历对象数组,如果对象成员包含与第二个参数所有键值对相同的键值对,就返回这个对象,最后返回符合要求的对象数组;

也就是说,如果第一个参数是[{name: 'suki', age: 21, gender: 'female'}, {name: 'cora', age: 22}, {name: 'suki'}],第二个参数是{name: 'suki', age: 21},最后的返回结果是[{name: 'suki', age: 21, gender: 'female'}];

换句话说,返回结果是一个新数组,由第一个参数中符合条件的对象组成,条件是第二个参数是这个对象的一个子集;

function whatIsInAName(collection, source) {
var arr = [];
var sourceKeys = Object.keys(source);
arr = collection.filter(obj => sourceKeys.every(key => source[key] === obj[key]));
return arr;
} whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
// [{ first: "Tybalt", last: "Capulet" }]

5. Spinal Tap Case


把字符串变成'aaa-bbb-ccc-ddd'这种格式,作为参数的字符串可能'thisIsSpinalTap' 这样的,也可能是'This Is<abbr>Spinal_Tap'这样的;虽然我的解法通过了测试,但自己觉得有点繁琐二球难看,如果你知道更简单的方法的话欢迎留言~

function spinalCase(str) {
var reg1 = /[^\w\s'].*[^\w\s']/g; // 匹配像<abbr>这种分隔符
str = str.replace(reg1, '-'); // 用短横线先做个记号分隔单词
var reg2 = /([A-Z])/g; // 有些单词之间没有分隔符,只靠后一个单词首字母大写来区分两个单词
str = str.replace(reg2, ($1) => '-' + $1.toLowerCase()); // 用短横线做个记号分隔单词并把大写字母转成小写字母
var reg3 = /[^a-zA-Z0-9']+/g;
str = str.replace(reg3, '-');
return str.replace(/^-/, '');
}
spinalCase('This Is Spinal Tap'); // 'this-is-spinal-tap'

6. Pig Latin


把英语单词转换成pig latin,也就是把单词开头的辅音字母(一个或连续多个)移到单词尾部再加上后缀'ay',如果单词不以辅音字母开头,直接在词尾加'way';

传进来的参数都是小写的英文单词;

function translatePigLatin(str) {
var consonants = /^[^aeiou]+/;
if (str.match(consonants) !== null) {
return RegExp.rightContext + RegExp.lastMatch + 'ay';
} else {
return str + 'way';
}
} translatePigLatin("consonant"); // 'onsonantcay'

7. Search and Replace


函数接收三个字符串参数(str, before, after),要求在str中找到before,然后用after替换掉它;

after的大小写要与before一致,如果before是'Dog',after是'cat',那么替换结果是'Cat';

function myReplace(str, before, after) {
var reg = new RegExp(before);
return str.replace(reg, match => {
if (/^[A-Z]/.test(match)) {
return after.replace(after[0], after[0].toUpperCase());
}
return after;
});
} myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
// "A quick brown fox leaped over the lazy dog"

8. DNA Pairing


传入一个DNA序列字符串,如'GCG',要求给DNA序列配对后,返回一个二维数组;

配对规则是'A'配'T','C'配'G';

返回的数组中的每一项是一对配对的DNA,如[["G", "C"], ["C","G"],["G", "C"]],传入的DNA字符串中的元素放在前面;

function pairElement(str) {
var re = [];
var strand = str.split('');
var pairing = new Map([['G', 'C'], ['C', 'G'], ['A', 'T'], ['T', 'A']]);
strand.forEach(ele => {
re.push([ele, pairing.get(ele)]);
});
return re;
} pairElement("GCG"); // [["G", "C"], ["C","G"],["G", "C"]]

9. Missing lette


接收一个字符串参数,要求找出字符串中缺失的字母并返回,如传入'abce',需要返回'd';如果传入的字符串没有缺失的字母,返回undefined;

function fearNotLetter(str) {
var arr = str.split('').map(char => char.charCodeAt(0));
var missing; for (var i = arr.length - 1; i >= 0; i--) {
if (arr[i] - arr[i - 1] > 1) {
missing = arr[i] - 1;
break;
}
if (i === 0) {
return undefined;
}
}
return String.fromCharCode(missing);
} fearNotLetter("abce"); // 'd'

10. Sorted Union


要求写一个函数,函数接收两个或以上数组作为参数,对这些数组进行去重后返回一个新数组,举个例子,传入参数为([1, 3, 2], [5, 2, 1, 4], [2, 1]),要求返回[1, 3, 2, 5, 4],数组里的数字的排列顺序跟它们在原数组的顺序一样;我的思路就是把所有传进来的数组合成一个新数组再去重;

function uniteUnique(...arrs) {
var arrUnion = arrs.reduce((a, b) => a.concat(b));
var re = new Set(arrUnion);
return [...re];
} uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]); // [1, 3, 2, 5, 4]

11. Convert HTML Entities


把传入的字符串中不符合HTML语法的字符进行转义,即对&, <, >, ", ' 进行转义;

function convertHTML(str) {
var convertRules = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&apos;'
};
return str.replace(/[&<>"']/g, match => convertRules[match]);
} convertHTML("Dolce & Gabbana"); // "Dolce &​amp; Gabbana"

12. Sum All Odd Fibonacci Numbers


传入一个正整数,返回一个斐波那契数列中小于等于这个正整数的奇数的和;

斐波那契数列开始两项分别是1和1,之后每一项都是前面两项的和;

我的思路是先把这个斐波那契数列中小于参数的项存在一个数组中,再遍历这个数组,求所有奇数的和;

function sumFibs(num) {
var fibNums = [1, 1];
for (var i = 0; i <= fibNums.length; i++) {
fibNums[i] = fibNums[i] ? fibNums[i] : (fibNums[i-1] + fibNums[i-2]);
if (fibNums[i] > num) {
fibNums.pop();
break;
}
}
var re = fibNums.reduce((a, b) => (b % 2 === 0) ? a : a + b, 0);
return re;
} sumFibs(4); //

13. Sum All Primes


传入一个正整数,返回小于等于这个正整数的所有质数的和;

function sumPrimes(num) {
function isPrime(n) {
for (let i = 2; i <= n / 2; i++) {
if (n % i === 0) {
return false;
}
}
return true;
} var re = 0;
for (let i = 2; i <= num; i++) {
if (isPrime(i)) {
re += i;
}
}
return re;
} sumPrimes(10); //

14. Smallest Common Multiple


传入一个数组,数组中有两个数字,要求求这两个个数字范围内的所有数字的最小公倍数;

例如,传入的数组是[1, 5],那么需要求得1, 2, 3, 4, 5这几个数字的最小公倍数,即60;

传入的数组中的数字不一定是升序排列的,也可能传入[5, 1];

我的思路是先填充一个新数组,得到参数数组范围内的所有数字;

要求得若干个数字的最小公倍数,先求两个数的最小公倍数,再求这个最小公倍数与第三个数的最小公倍数,重复操作即可得到结果;

求两个数的最小公倍数时,我先使用更相减损法求得两数的最大公约数,再用公式求两数的最小公倍数;

function smallestCommons(arr) {
// 使用arr范围内的数字填充新数组
var newArr = [];
var start, end;
if (arr[0] - arr[1] < 0) {
start = arr[0];
end = arr[1];
} else {
start = arr[1];
end = arr[0];
} for (let i = start; i <= end; i++) {
newArr.push(i);
} // 求数组所有项的最小公倍数
var re = newArr.reduce((a, b) => {
var num1 = a
,num2 = b;
// 先求两个数的最大公约数
// 第一步:如果两个数都是偶数,先约简
// 否则直接开始第二步
var multiply2 = 1;
while ((num1 % 2 === 0) & (num2 % 2 === 0)) {
num1 /= 2;
num2 /= 2;
multiply2 *= 2;
}
// 第二步:更相减损法求最大公约数
// 以大数减小数,得到的等数与减数比较,再用较大数减较小数
// 重复上面的操作,直到得到的等数与减数相等
var bigNum, smallNum, diff;
if (num1 > num2) {
bigNum = num1;
smallNum = num2;
} else {
bigNum = num2;
smallNum = num1;
}
diff = bigNum - smallNum; while (diff !== smallNum) {
if (smallNum > diff) {
bigNum = smallNum;
smallNum = diff;
} else {
bigNum = diff;
}
diff = bigNum - smallNum;
}
// 第一步中约简掉的'2'与第二步中得到的等数的乘积就是两个数的最大公约数
var biggestCommonDivisor = diff * multiply2; // 求最小公倍数
// 两个数的乘积等于两数最大公约数与最小公倍数的乘积
var smallestCommonMultiple = a * b / biggestCommonDivisor;
// 得到的最小公倍数再与下一个数求最小公倍数
// 重复操作即可得到若干个数的最小公倍数
return smallestCommonMultiple;
});
return re;
} smallestCommons([1,5]); //

15. Drop it


函数接收两个参数,一个数组(arr),一个函数(func);

要求从索引0开始遍历数组(arr),把数组项作为参数传给函数(func),如果函数(func)返回false,则去掉这一项,直到数组项满足函数(func)的要求返回true,停止遍历,返回余下的数组部分;

function dropElements(arr, func) {
while (!func(arr[0])) {
arr.shift();
}
return arr;
} dropElements([1, 2, 3], function(n) {return n < 3; }); // [3, 4]

16. Steamroller


传入一个多维数组,要求把它完全展开;

我的思路是,给函数增加一个参数re用于存储展开后的数组项,它的默认值是一个空数组;

在函数中,遍历多维数组,对每一个数组项进行判断,如果数组项不是数组,把这一项推到re中,如果数组项是数组,那就再调用steamrollArray函数,把这一项和re作为参数传进函数;遍历完成后返回结果;

function steamrollArray(arr, re=[]) {
arr.forEach(ele => {
if (!Array.isArray(ele)) {
re.push(ele);
} else {
steamrollArray(ele, re);
}
});
return re;
}
steamrollArray([1, [2], [3, [[4]]]]); // [1, 2, 3, 4]

17. Binary Agents


传入一个二进制数字构成的字符串,要求把这个字符串翻译成英文,二进制数字之间以空格隔开;

function binaryAgent(str) {
var arr = str.split(' ').map(ele => {
// 把每个二进制数字字符串转换成十进制数字,再转成英文字母
return String.fromCharCode(parseInt(ele, 2));
});
return arr.join('');
} binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111");
// "Aren't bonfires fun!?"

18. Everything Be True


传入两个参数,第一个是由对象组成的数组,第二个是一个对象属性字符串,如果在数组的每一个对象中,与第二个参数同名的属性都为真值,函数返回true,否则返回false;

function truthCheck(collection, pre) {
return collection.every(obj => !!obj[pre]); // 我在这里使用了!!是因为觉得这样比较好理解,去掉结果也是一样的
} truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");
// true

19. Arguments Optional


写一个函数,这个函数接收一个或两个参数,如果传入两个参数(a, b),返回两个参数的和;

如果传入一个参数(a),返回一个接收一个参数(b)的函数,该函数返回外部函数参数a和自身参数b的和;

如果任意一个参数不是数字,函数返回undefined;

function addTogether(...arg) {
if (arg.every(ele => (typeof ele) == 'number')) {
return arg.length === 2 ? arg[0] + arg[1] : function(n) {
return (typeof n) == 'number' ? arg[0] + n : undefined;
};
} else {
return undefined
}
} var sumTwoAnd = addTogether(2);
sumTwoAnd(3); //

20. Make a Person


有一个Person构造函数,需要在这个构造函数中增加以下方法:

getFirstName(),getLastName(),getFullName(),setFirstName(first),setLastName(last),setFullName(firstAndLast)

其中那些接收一个参数的方法必须接收一个字符串参数;要求这些方法是唯一能与对象交互的方法;

var Person = function(firstAndLast) {
// 定义私有变量
var firstName = firstAndLast.split(' ')[0]
,lastName = firstAndLast.split(' ')[1]; this.getFirstName = function() {
return firstName;
};
this.getLastName = function() {
return lastName;
};
this.getFullName = function() {
return this.getFirstName() + ' ' + this.getLastName();
}; this.setFirstName = function(first) {
firstName = first;
};
this.setLastName = function(last) {
lastName = last;
};
this.setFullName = function(firstAndLast) {
firstName = firstAndLast.split(' ')[0]
,lastName = firstAndLast.split(' ')[1]
}
}; var bob = new Person('Bob Ross');
bob.getFullName(); // 'Bob Ross'
bob.setFirstName('Haskell');
bob.getFullName(); // 'Haskell Ross'

FCC-js算法题解题笔记的更多相关文章

  1. PAT算法题学习笔记

    1001. 害死人不偿命的(3n+1)猜想 (15) 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去, ...

  2. js算法题

    //较Low,看到的大神 帮补充 1.给定一个数组:,定义一个函数获取数组中所有的奇数,返回一个新数组:var arr1=[1,3,4,5,6,7,8,3,4,2,3,6];    function ...

  3. FCC上的初级算法题

    核心提示:FCC的算法题一共16道.跟之前简单到令人发指的基础题目相比,难度是上了一个台阶.主要涉及初步的字符串,数组等运算.仍然属于基础的基础,官方网站给出的建议完成时间为50小时,超出了之前所有非 ...

  4. FCC上的javascript算法题之中级篇

    FCC中的javascript中级算法题解答 中级算法的题目中用到了很多js的知识点,比如迭代,闭包,以及对json数据的使用等等,现在将自己中级算法的解答思路整理出来供大家参考讨论.欢迎大家提出新的 ...

  5. js 中的算法题,那些经常看到的

    js中遇到的算法题不是很多,可以说基本遇不到.但面试的时候,尤其是一些大公司,总是会出这样那样的算法题,考察一个程序员的逻辑思维能力.如下: 1.回文. 回文是指把相同的词汇或句子,在下文中调换位置或 ...

  6. FCC的javascript初级算法题解答

    FCC上的javascript基础算法题 前一阵子做的基础算法题,感觉做完后收获还蛮大的,现在将自己的做法总结出来,供大家参考讨论.基本上做到尽量简短有效,但有些算法还可以继续简化,比如第七题若采用正 ...

  7. 19道常见的JS面试算法题

    最近秋招也做了多多少少的面试题,发现除了基础知识外,算法还是挺重要的.特意整理了一些常见的算法题,添加了自己的理解并实现. 除此之外,建议大家还可以刷刷<剑指offer>.此外,左神在牛客 ...

  8. 2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

    2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案 1.题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. ...

  9. CTF实验吧-WEB题目解题笔记(1)简单的登陆题

    1.简单的登陆题 解题链接: http://ctf5.shiyanbar.com/web/jiandan/index.php  Burp抓包解密 乱码,更换思路.尝试id intruder 似乎也没什 ...

随机推荐

  1. OpenGL.tutorial06键盘和鼠标

    1.这个图是用 Excel画的 简单示意图(单元格边框,视图-->网格线) 1.1.中间的 正立方体 处于 X/Y/Z轴的中心,边长为2 ZC:代码中 原版是 人物在 (0,0,5)处,水平夹角 ...

  2. (转)关于request.getServletPath(),request.getContextPath()的总结

    文章完全转载自 : https://blog.csdn.net/qq_27770257/article/details/79438987 最近对于request中的几种“路径”有点混淆,查找网上资源都 ...

  3. HTML和CSS查缺补漏

    margin的问题: 1.margin-top向上传递 解决:1.父元素border边框,2.父元素使用overflow:hidden 3.为父元素或者子元素声明绝对定位,4.为父元素或者子元素声明浮 ...

  4. redis缓存中间件基础

    前序: 默认使用SimpleCacheConfiguration 组件ConcurrentMapCacheManager==ConcurrentMapCache将数据保存在ConcurrentMap& ...

  5. WPF界面假死

    首先要检查那些滥用 Timer.Dispacher Timer 或者滥用什么“线程+死循环+阻塞”轮询的代码. 这种是编程大忌,有些人不会设计事件驱动程序,而是滥用轮询. 若是:触发事件后的假死,搜W ...

  6. Vue.js——60分钟快速入门(转)

    vue:Vue.js——60分钟快速入门 <!doctype html> <html lang="en"> <head> <meta ch ...

  7. node.js 生成二维码

    因为自己的项目中,想在商品详情页上 显示一个 商品优惠券的二维码. 以此为需求. node.js 后台代码 const qr_image = require("qr-image") ...

  8. Azure中block和Page的比较 Azure: Did You Know? Block vs Page Blobs

    Azure storage service supports two types of blobs (blob, or BLOB, stand for Binary Large OBject, i.e ...

  9. spring的历史和哲学

    (1) 春天来了—— Spring 来了! Spring 在起源可以回溯到 Rod Johnson 编写的“ Expert One-to-One J2EE Design and Development ...

  10. 图融合之加载子图:Tensorflow.contrib.slim与tf.train.Saver之坑

    import tensorflow as tf import tensorflow.contrib.slim as slim import rawpy import numpy as np impor ...