首页 技术 正文
技术 2022年11月18日
0 收藏 679 点赞 4,585 浏览 8964 个字

题目链接: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'
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,489
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,904
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,737
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,490
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,128
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,290