Freecodecamp 算法題 (二)
1. Sum All Numbers in a Range
我們會傳遞給你一個包含兩個數(shù)字的數(shù)組。返回這兩個數(shù)字和它們之間所有數(shù)字的和。
最小的數(shù)字并非總在最前面。
function sumAll(arr) {
var sum=0;
if(arr[0]<arr[1]){
for(let i=arr[0]; i<=arr[1];i++){
sum+=i;
}
}
else if(arr[1]<arr[0]){
for(let k=arr[1]; k<=arr[0];k++){
sum+=k;
}
}
return sum;
}
sumAll([1, 4]);
第二種方法:
Math.max()
Math.min()
Array.reduce()
function sumAll(arr) {
var max = Math.max(arr[0],arr[1]);
var min = Math.min(arr[0],arr[1]);
var sum =0;
for (var i=min;i<= max;i++){
sum+= i;
}
return sum;
}
sumAll([1, 4]);
2. Diff Two Arrays
比較兩個數(shù)組,然后返回一個新數(shù)組,該數(shù)組的元素為兩個給定數(shù)組中所有獨有的數(shù)組元素。換言之,返回兩個數(shù)組的差異。
function diff(arr1, arr2) {
return arr1.filter(function(e){
return arr2.indexOf(e) === -1;
}).concat(arr2.filter(function(e){
return arr1.indexOf(e) === -1;
}));
}
diff([1, 2, 3, 5], [1, 2, 3, 4, 5]); // [4]
3. Roman Numeral Converter
將給定的數(shù)字轉(zhuǎn)換成羅馬數(shù)字。
所有返回的 羅馬數(shù)字 都應(yīng)該是大寫形式。
function convert(num) {
var number = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
var roman_number =["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"];
var result = "";
number.forEach(function(item,index,array){
while(num>=item){
//如果num大于number數(shù)組中的數(shù)
result += roman_number[index]; //將這個數(shù)對應(yīng)的羅馬數(shù)字加到result中 num -=item; //減去這個數(shù),直到結(jié)束。
}
});
return result;
}
convert(36);
4. Where art thou
寫一個 function,它遍歷一個對象數(shù)組(第一個參數(shù))并返回一個包含相匹配的屬性-值對(第二個參數(shù))的所有對象的數(shù)組。如果返回的數(shù)組中包含 source 對象的屬性-值對,那么此對象的每一個屬性-值對都必須存在于 collection 的對象中。
例如,如果第一個參數(shù)是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }],第二個參數(shù)是 { last: "Capulet" },那么你必須從數(shù)組(第一個參數(shù))返回其中的第三個對象,因為它包含了作為第二個參數(shù)傳遞的屬性-值對。
function where(collection, source) {
//source 的key
var keys = Object.keys(source);
var arr =[];
arr = collection.filter(function(item){
for(var i=0;i<keys.length;i++){
if(!item.hasOwnProperty(keys[i]) || item[keys[i]]!== source[keys[i]]){
return false;
}
}
return true;
});
return arr;
}
where([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
思路
如果把一個對象表示為 {key1: value1,key2: value2,...,keyN: valueN} 形式,那么 Object.keys() 就能拿到 [key1,key2,...,keyN] 的集合。Object.keys() 方法會返回一個由給定對象的所有可枚舉自身屬性的屬性名組成的數(shù)組,數(shù)組中屬性名的排列順序和使用for-in循環(huán)遍歷該對象時返回的順序一致。
我們先拿到 source 的 key 值,然后再一一與 collection 中的每一項比較。
var keys = Object.keys(source);
var arr = collection.filter(function(item){
//do something...
});
obj.hasOwnProperty(prop) 在屬性 prop 存在于對象實例時返回 true。
if(!item.hasOwnProperty(keys[i]) || item[keys[i]]!== source[keys[i]]){
return false;
}
解釋這個if判斷語句:當(dāng) collection 的某一項不存在屬性 keys[i]時(!item.hasOwnProperty(keys[i]),返回 false;
item[keys[i]]!== source[keys[i]])
item 在 key 值為 keys[i] 時 value 值不等于同 key 值時 source 的 value值,返回 false.
5. Search and Replace
使用給定的參數(shù)對句子執(zhí)行一次查找和替換,然后返回新句子。
第一個參數(shù)是將要對其執(zhí)行查找和替換的句子。
第二個參數(shù)是將被替換掉的單詞(替換前的單詞)。
第三個參數(shù)用于替換第二個參數(shù)(替換后的單詞)。
注意:替換時保持原單詞的大小寫。例如,如果你想用單詞 "dog" 替換單詞 "Book" ,你應(yīng)該替換成 "Dog"。
function myReplace(str, before, after) {
if(before[0] === before[0].toUpperCase()){
after = after[0].toUpperCase()+after.slice(1);
}
return str=str.replace(before, after);
}
myReplace("A quick brown fox jumped over the lazy dog", "jumped", "leaped");
6. Pig Latin
把指定的字符串翻譯成 pig latin。
Pig Latin 把一個英文單詞的第一個輔音或輔音叢(consonant cluster)移到詞尾,然后加上后綴 "ay"。
如果單詞以元音開始,你只需要在詞尾添加 "way" 就可以了
function translate(str) {
var temp = ['a','e','i','o','u'];
if(temp.indexOf(str[0])>=0){
return str+ 'way';
}
while(temp.indexOf(str[0])<0){
str = str.substr(1)+str.substr(0,1);
}
return str+'ay';
}
translate("california");
7. DNA Pairing
DNA 鏈缺少配對的堿基。依據(jù)每一個堿基,為其找到配對的堿基,然后將結(jié)果作為第二個數(shù)組返回。
Base pairs(堿基對) 是一對 AT 和 CG,為給定的字母匹配缺失的堿基。
在每一個數(shù)組中將給定的字母作為第一個堿基返回。
例如,對于輸入的 GCG,相應(yīng)地返回 [["G", "C"], ["C","G"],["G", "C"]]
字母和與之配對的字母在一個數(shù)組內(nèi),然后所有數(shù)組再被組織起來封裝進一個數(shù)組。
方法一 :
function pair(str) {
var arr = str.split('');
var pair = '';
var result = arr.map(function(item,index,array){
switch(item){
case 'A':
pair = 'T';
break;
case 'T':
pair = 'A';
break;
case 'C':
pair = 'G';
break;
case 'G':
pair = 'C';
break;
}
return [item,pair];
});
return result;
}
pair("GCG");
方法二:
function pair(str) {
var obj = {'A':'T','T':'A','G':'C','C':'G'};
var result =str.split('').map(e=>[e,obj[e]]);
return result;
}
pair("GCG");
8. Missing letters
從傳遞進來的字母序列中找到缺失的字母并返回它。
如果所有字母都在序列中,返回 undefined。
function fearNotLetter(str) {
for(let i=0;i<str.length;i++){
if(str.charCodeAt(i+1)-str.charCodeAt(i)>1){
return String.fromCharCode(str.charCodeAt(i)+1);
}
}
return undefined;
}
fearNotLetter("abce");
9. Boo who
檢查一個值是否是基本布爾類型,并返回 true 或 false。
基本布爾類型即 true 和 false。
function boo(bool) {
// What is the new fad diet for ghost developers? The Boolean.
return typeof bool==='boolean';
}
boo(null);
10. Sorted Union
寫一個 function,傳入兩個或兩個以上的數(shù)組,返回一個以給定的原始數(shù)組排序的不包含重復(fù)值的新數(shù)組。
換句話說,所有數(shù)組中的所有值都應(yīng)該以原始順序被包含在內(nèi),但是在最終的數(shù)組中不包含重復(fù)值。
非重復(fù)的數(shù)字應(yīng)該以它們原始的順序排序,但最終的數(shù)組不應(yīng)該以數(shù)字順序排序。
function unite(arr1, arr2, arr3) {
var args = Array.from(arguments);
var arr = args.reduce(function(prev,cur,index,array){
return prev.concat(cur);
});
var result = arr.filter(function(item,index){
return arr.indexOf(item)===index;
});
return result;
}
unite([1, 3, 2], [5, 2, 1, 4], [2, 1]);
注意:
數(shù)組去重的最直接的方法
var result = arr.filter(function(item,index){
return arr.indexOf(item)===index;
});
11. Convert HTML Entities
將字符串中的字符 &、<、>、" (雙引號), 以及 ' (單引號)轉(zhuǎn)換為它們對應(yīng)的 HTML 實體。
function convert(str) {
var htmlEntities = {
'&':'&',
'<':'<',
'>':'>',
'\"':'"',
'\'':"'"
};
str = str.split('').map(function(entity){
return htmlEntities[entity] || entity;
});
return str.join('');
}
convert("Dolce & Gabbana");
12. Spinal Tap Case
將字符串轉(zhuǎn)換為 spinal case。Spinal case 是 all-lowercase-words-joined-by-dashes 這種形式的,也就是以連字符連接所有小寫單詞。
- spinalCase("This Is Spinal Tap") 應(yīng)該返回 "this-is-spinal-tap"。
- spinalCase("thisIsSpinalTap") 應(yīng)該返回 "this-is-spinal-tap"。
- spinalCase("The_Andy_Griffith_Show") 應(yīng)該返回 "the-andy-griffith-show"。
- spinalCase("Teletubbies say Eh-oh") 應(yīng)該返回 "teletubbies-say-eh-oh"。
function spinalCase(str) {
return str.replace(/\s|_/g,'-').replace(/([a-z])([A-Z])/g,'$1-$2').toLowerCase();
}
spinalCase('thisIsSpinalTap');
13. Sum All Odd Fibonacci Numbers
給一個正整數(shù)num,返回小于或等于num的斐波納契奇數(shù)之和。
斐波納契數(shù)列中的前幾個數(shù)字是 1、1、2、3、5 和 8,隨后的每一個數(shù)字都是前兩個數(shù)字之和。
function sumFibs(num) {
var prev = 0;
var cur = 1;
var sum = 0;
while(cur <= num){
if(cur%2 !== 0){
sum += cur;
}
cur += prev;
prev = cur - prev;
}
return sum;
}
sumFibs(4);
14. Sum All Primes
求小于等于給定數(shù)值的質(zhì)數(shù)之和。
只有 1 和它本身兩個約數(shù)的數(shù)叫質(zhì)數(shù)。例如,2 是質(zhì)數(shù),因為它只能被 1 和 2 整除。1 不是質(zhì)數(shù),因為它只能被自身整除。
給定的數(shù)不一定是質(zhì)數(shù)。
function sumPrimes(num) {
if(num===1) return false;
function checkPrime(i){
for(var k=2;k<i;k++){
if(i%k===0){
return false;
}
}
return true;
}
var sum=0;
for(var i=2;i<=num;i++){
if(checkPrime(i)){
sum+=i;
}
}
return sum;
}
sumPrimes(10);
15. Smallest Common Multiple
找出能被兩個給定參數(shù)和它們之間的連續(xù)數(shù)字整除的最小公倍數(shù)。
范圍是兩個數(shù)字構(gòu)成的數(shù)組,兩個數(shù)字不一定按數(shù)字順序排序。
例如對 1 和 3 —— 找出能被 1 和 3 和它們之間所有數(shù)字整除的最小公倍數(shù)。
思路:假如區(qū)間為[1,5],所求的數(shù)值是60,也就是說需要求出來的值是的1,2,3,4,5的公倍數(shù)。
兩個數(shù)字最小公倍數(shù)的求法:A*B/(AB兩數(shù)的最大公約數(shù))
function smallestCommons(arr) {
arr = arr.sort(function(a,b){
return a-b;
});
var num = arr[0];
for(var i=num;i<=arr[1];i++){
num*= i/gcd(num,i);
}
return num;
}
//歐幾里得算法 求最大公約數(shù)
function gcd(m,n){
if(m%n===0){
return n;
}else{
return gcd(n,m%n);
}
}
smallestCommons([1,5]);
16. Finders Keepers
寫一個 function,它遍歷數(shù)組 arr,并返回數(shù)組中第一個滿足 func 返回值的元素。舉個例子,如果 arr 為 [1, 2, 3],func 為 function(num) {return num === 2; },那么 find 的返回值應(yīng)為 2。
function find(arr, func) {
var num = 0;
num = arr.filter(func);
return num[0];
}
find([1, 2, 3, 4], function(num){ return num % 2 === 0; });
17. Drop it
讓我們來丟棄數(shù)組(arr)的元素,從左邊開始,直到回調(diào)函數(shù)return true就停止。
第二個參數(shù),func,是一個函數(shù)。用來測試數(shù)組的第一個元素,如果返回fasle,就從數(shù)組中拋出該元素(注意:此時數(shù)組已被改變),繼續(xù)測試數(shù)組的第一個元素,如果返回fasle,繼續(xù)拋出,直到返回true。
最后返回數(shù)組的剩余部分,如果沒有剩余,就返回一個空數(shù)組。
function drop(arr, func) {
while(arr.length>0 && !func(arr[0])){
arr.shift();
}
return arr;
}
drop([1, 2, 3], function(n) {return n < 3; });
18. Steamroller
對嵌套的數(shù)組進行扁平化處理。你必須考慮到不同層級的嵌套。
steamroller([[["a"]], [["b"]]]) 應(yīng)該返回 ["a", "b"]。
steamroller([1, [2], [3, [[4]]]]) 應(yīng)該返回 [1, 2, 3, 4]。
steamroller([1, [], [3, [[4]]]]) 應(yīng)該返回 [1, 3, 4]。
steamroller([1, {}, [3, [[4]]]]) 應(yīng)該返回 [1, {}, 3, 4]。
function steamroller(arr) {
var tempArr = [];
// I'm a steamroller, baby
function falttenArray(arg){
if(!Array.isArray(arg)){
tempArr.push(arg);
}else{
for(var i in arg){
falttenArray(arg[i]);
}
}
}
arr.forEach(falttenArray);
return tempArr;
}
steamroller([1, [2], [3, [[4]]]]);
19. Binary Agents
傳入二進制字符串,翻譯成英語句子并返回。
二進制字符串是以空格分隔的。
function binaryAgent(str) {
str = str.split(' ');
var arr =[];
var result=[];
for(var i=0;i<str.length;i++){
arr.push(parseInt(str[i],2));
result.push(String.fromCharCode(arr[i]));
}
return result.join('');
}
binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111");
19. Everything Be True
所有的東西都是真的!
完善編輯器中的every函數(shù),如果集合(collection)中的所有對象都存在對應(yīng)的屬性(pre),并且屬性(pre)對應(yīng)的值為真。函數(shù)返回ture。反之,返回false。
記?。耗阒荒芡ㄟ^中括號來訪問對象的變量屬性(pre)
function every(collection, pre) {
// Is everyone being true?
return collection.every(function(val){
return val[pre];
});
}
every([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");
20. Arguments Optional
創(chuàng)建一個計算兩個參數(shù)之和的 function。如果只有一個參數(shù),則返回一個 function,該 function 請求一個參數(shù)然后返回求和的結(jié)果。
例如,add(2, 3) 應(yīng)該返回 5,而 add(2) 應(yīng)該返回一個 function。
調(diào)用這個有一個參數(shù)的返回的 function,返回求和的結(jié)果:
var sumTwoAnd = add(2);
sumTwoAnd(3) 返回 5。
如果兩個參數(shù)都不是有效的數(shù)字,則返回 undefined。
function add() {
var args = Array.from(arguments);
if(typeof args[0] ==='number' && typeof args[1]==='number'){
return args[0]+args[1];
}
if(args.length===1 && typeof args[0] ==='number'){
return function(y){
if(typeof y==='number') {
return args[0]+y;
}
};
}
}
add(2,3);