题目链接: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. Effective java 系列之异常转译

    异常转译:当位于最上层的子系统不需要关心底层的异常细节时,常见的作法时捕获原始异常,把它转换一个新的不同类型的异常,在将新异常抛出. 通常方法捕获底层异常,然后抛高层异常. public static ...

  2. 【sock_stream和sock_dgram】、 【AF_INET和AF_UNIX】

    [sock_stream和sock_dgram] 1.sock_stream 是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料(如文件)传送. 2.sock_dgram 是无 ...

  3. python-Excel读取-合并单元格读取

    python-Excel读取-合并单元格读取(后续会补充python-Excel写入的部分) 1. python读取Excel单元格 代码包含读取Excel中数据,以及出现横向合并单元格,以及竖向合并 ...

  4. magic

  5. python学习之读写csv文件(使用pandas)

    简介 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本).纯文本意味着该文件是一个字符序 ...

  6. async-await用法

    转载:https://segmentfault.com/a/1190000011526612?utm_source=tag-newest

  7. font——文字属性大全

    一.字体风格(font-style) <style type="text/css"> /*默认值.浏览器显示一个标准的字体样式.*/ p.normal {font-st ...

  8. mac系统 安装pip,用python读写excel(xlrd、xlwt)安装

    1: 先安装python, 下载地址:https://www.python.org/downloads/release/python-372/ 2: 安装pip 下载一个get-pip.py的文件  ...

  9. python小游戏,石头/剪子/布

    #从控制台输入石头(1)/剪子(2)/布(3) player=int(input("玩家出拳 石头(1)/剪子(2)/布(3)")) #电脑随机出拳 computer comput ...

  10. 创建nodejs服务

    1.终端窗口输入:npm init 2.终端输入:npm install 3.修改代码后重启服务:ctrl+c 启动服务:node 文件名.js