FreeCodeCamp( FCC)前端工程師 中級算法練習 分析與解答(全)(精)
阿新 • • 發佈:2018-02-01
前端工程師 doc html agents fad asc -keep tps nts
[TOC]
說在前面
這是要一篇非常簡單的新手能看懂的文章,希望你喜歡。由於在 freecodecamp 中貌似!?無法使用 ES6
的某些語法,未測試具體。所以基本上用古老?!的ES5,4
寫成,謝謝。在寫本博文前沒有參考過別人的做法,純手打,我的方法肯定不是最好,只是以我自己喜歡的方式在寫而已。
純原創,轉載請聯系作者https//:[email protected]
、[email protected]
。
- freecodecamp China
- 不明白
API
請參考MDN給出的解釋 - 個別題目沒有判斷函數參數及其類型,僅通過了
Run tests
- 如果你最近在寫微信小程序的藍牙的話請參考wx-bluetooth
- 有疑惑請留言
開始
Sum All Numbers in a Range
- 先對傳入數組升序排列,拿到 [min, max]
- 然後 generateArr 成一個 [min, min+1, min+2, ..., max]
- Array.prototype.reduce 方法從左至右求和
function sumAll(arr) {
if (!Array.isArray(arr) || !arr || !arr.length) return;
arr = arr.sort(function(a, b){ return a-b;});
arr = generateArr(arr[0 ], arr[1]);
console.log(arr);
return arr.reduce(function(accu, curr){
return accu += curr;
});
}
function generateArr(min, max) {
var arr = [];
while (min <= max) {
arr.push(min);
min++;
}
return arr;
}
Diff Two Arrays
- 合並兩個數組成一個數組
- 通過一個 obj 緩存數組中每項的出現次數
- 返回 obj[arr[i]] 僅出現一次的項組成的數組
function diff(arr1, arr2) {
if (!Array.isArray(arr1) || !Array.isArray(arr2)) return;
var newArr = arr1.concat(arr2);
return unique(newArr);
}
function unique(arr) {
var a = [], i, l, item, key, obj = {};
for (i = 0, l = arr.length; i < l; i++) {
item = arr[i];
if (obj[item] === undefined) {
obj[item] = [item];
} else {
obj[item].push(item);
}
}
console.log(arr, obj);
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key].length === 1){
a = a.concat(obj[key]);
}
}
}
return a;
}
Roman Numeral Converter
- 先把每個數所對應的阿拉伯數字和羅馬數字取出來並一一對應
var RomanNumArr = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
RomanNumStrArr = [‘M‘, ‘CM‘, ‘D‘, ‘CD‘, ‘C‘, ‘XC‘, ‘L‘, ‘XL‘, ‘X‘, ‘IX‘, ‘V‘, ‘IV‘, ‘I‘];
- 然後對給出的數進行 倒推求余 的推算並返回對應數字數組,比如139 = [100 + 39] = [100 + 3 * 10 + 9] = [100, 10, 10, 10, 9]
function getSeparatedRomanNumArr (num, arr) {
arr = arr || [];
for (var i = 0, l = RomanNumArr.length; i < l; i++) {
var curr = RomanNumArr[i], next, int;
if (num >= curr) {
if (num % curr === 0) {
return pushNumByTimes2Arr(curr, num / curr, arr);
} else {
next = num % curr;
int = num - next;
return getSeparatedRomanNumArr(next, pushNumByTimes2Arr(curr, int / curr, arr));
}
}
}
}
function pushNumByTimes2Arr(num, times, arr) {
while (times) {
arr.push(num);
times--;
}
return arr;
}
- 將每個阿拉伯數字對上羅馬數字,然後對返回的數組進行 Array.prototype.join 即可,例如上面例子139 = [100, 10, 10, 10, 9] = [‘C‘, ‘X‘, ‘X‘, ‘X‘, ‘IX‘].join(‘‘) = ‘CXXXIX‘
function convert(num) {
if (!num || ‘number‘ !== typeof +num) throw new TypeError();
var romanNumArr = getSeparatedRomanNumArr(num);
return romanNumArr.map(function(item){
return RomanNumStrArr[RomanNumArr.indexOf(item)];
}).join(‘‘);
}
Where art thou
for
loop取出collection
中的每個對象的keys
然後與source
對象的keys
進行比對通過函數getSameItems
- 將當前
collection[i]
的key
的與sameKeys
進行比對,如果全部全等就match
反正false
function where(collection, source) {
var arr = [], sourceKeys = Object.keys(source), obj, key, objKeys,
sameKeys, i, l = collection.length, j, k, matched;
for (i = 0; i < l; i++) {
obj = collection[i];
objKeys = Object.keys(obj);
if (objKeys.length < sourceKeys.length) continue;
sameKeys = getSameItems(sourceKeys, objKeys);
if (sameKeys.length < sourceKeys.length) continue;
matched = true;
if (sameKeys && sameKeys.length) {
for (j = 0, k = sameKeys.length; j < k; j++) {
key = sameKeys[j];
if (obj[key] !== source[key]) {
matched = false;
}
}
}
if (matched) arr.push(obj);
}
return arr;
}
function getSameItems (arr1, arr2) {
if (!arr1 || !arr1.length || !arr2 || !arr2.length) throw new TypeError();
var arr = [];
arr1.forEach(function(item){
if (~arr2.indexOf(item)) {
arr.push(item);
}
});
return arr;
}
Search and Replace
function myReplace(str, before, after) {
after = isUpperCase(before[0]) ? camelize(after) : after;
str = str.replace(before, after);
return str;
}
function camelize (str) {
return str.slice(0, 1).toUpperCase() + str.slice(1, str.length);
}
function isUpperCase(s) {
return s === s.toUpperCase();
}
Pig Latin
- 根據題意先寫出元音數組
vowels
,然後分割字符串成數組並比對是否存在元音字符,如果有則立即返回該index
位置,反之返回undefined
- 如果
index === 0
則返回str + ‘way‘
反之返回str.slice(vowelIndex, str.length) + str.substr(0, vowelIndex) + ‘ay‘
;
function translate(str) {
var vowelIndex = findVowelsIndex(str);
str = vowelIndex === 0 ? str + ‘way‘ : str.slice(vowelIndex, str.length) + str.substr(0, vowelIndex) + ‘ay‘;
return str;
}
function findVowelsIndex (str) {
var vowels = [‘a‘, ‘e‘, ‘i‘, ‘o‘, ‘u‘];
var strArr = str.split(‘‘), i, l, index;
for (i = 0, l = strArr.length; i < l; i++) {
index = vowels.indexOf(strArr[i]);
if (~index) {
return i;
}
}
}
DNA Pairing
function pair(str) {
var strArr = str.split(‘‘), pairArr = [], pair, i, l;
for (i = 0, l = strArr.length; i < l; i++) {
switch(strArr[i]){
case ‘C‘:
pair = ‘G‘;
break;
case ‘G‘:
pair = ‘C‘;
break;
case ‘A‘:
pair = ‘T‘;
break;
case ‘T‘:
pair = ‘A‘;
break;
}
pairArr.push([strArr[i], pair]);
}
return pairArr;
}
Missing letters
- 比對給出的
str
的每個字符,並全部轉換成 - 如果當前字符的 charCode 不等於
next
的charCode
則找到了該 迷失字符
function fearNotLetter(str) {
var strArr, i, l, curr, next, noMissing = true;
strArr = str.split(‘‘).map(function(word){
return word.charCodeAt();
});
for (i = 0, l = strArr.length; i < l; i++) {
curr = strArr[i];
next = strArr[i + 1];
console.log(‘curr:‘, curr, ‘next:‘, next);
if (i !== l - 1 && ++curr !== next) {
str = String.fromCharCode(curr);
noMissing = false;
break;
}
}
return noMissing ? undefined : str;
}
Boo who
function boo(bool) {
// What is the new fad diet for ghost developers? The Boolean.
if (typeof bool !== ‘boolean‘) return false;
return true;
}
Sorted Union
function unite(arr1, arr2, arr3) {
return Array.prototype.reduce.call(arguments, function(accu, curr){
console.log(‘accu:‘, accu);
console.log(‘curr:‘, curr);
curr = curr.filter(function(item){
return !~accu.indexOf(item);
});
return accu.concat(curr);
});
}
Convert HTML Entities
function convert(str) {
var i, j, reg, chars = [‘&‘, ‘<‘, ‘>‘, ‘"‘, "‘"], strs = [‘&‘, ‘<‘, ‘>‘, ‘"‘, ‘'‘];
for (i = 0, l = chars.length; i < l; i++) {
reg = new RegExp(‘\\‘ + chars[i], ‘gm‘);
str = str.replace(reg, strs[i]);
}
return str;
}
Spinal Tap Case
function spinalCase(str) {
// "It‘s such a fine line between stupid, and clever."
// not, there is a comma still.
// --David St. Hubbins
var reg1 = /(\s|\_)/g, reg2 = /([A-Z])/g;
if (reg1.test(str)) {
str = str.replace(reg1, ‘-‘);
} else if (reg2.test(str)) {
str = str.replace(reg2, ‘-$1‘);
}
str = str.toLowerCase();
return str;
}
Sum All Odd Fibonacci Numbers
- 先拿到斐波那契中所有小於 num 的數
- 然後求該數組中所有奇數(odd)項的和
function sumFibs(num) {
if (num <= 2) return num;
var a = 1, b = 1, arr = [a, b], sum = 0, i, l;
while (sum < num) {
sum = a + b;
if (sum <= num) arr.push(sum);
a = b;
b = sum;
}
console.log(arr);
num = 0;
for (i = 0, l = arr.length; i < l; i++) {
if (arr[i] % 2 !== 0) {
num += arr[i];
}
}
return num;
}
Sum All Primes
- 先將所有數組轉出來(抱歉這裏用了ES6的新方法
Array.from
,請參考MDN Array.from) - 判斷每一個數是否是質數,通過函數isPrime
function sumPrimes(num) {
return Array.from({length: num}).map(function(item, index){
return ++index;
}).filter(function(item){
return isPrime(item);
}).reduce(function(accu, curr){
return accu += curr;
});
}
function isPrime (num) {
if (num <= 1) return;
var i, l, prime = true;
for (i = 2, l = num / 2 + 1; i < l; i++) {
if (num % i === 0) {
prime = false;
break;
}
}
return prime;
}
Smallest Common Multiple
PS: 這又是一個繼羅馬數字後不錯的中級算法題
先上一波我用到的資料(即思路):
- 一個優秀的答案
- Git上老外的答案
- 如何求最小公倍數,我選用該帖子中 分解質因數法,所以我們得先求出所有的該區間中每個數的質因數數組,然後去重,最後乘上所有數的質因數
- 歐幾裏德算法
- 最大公約數
- 質因數分解
一個優秀的答案,同時向歐幾裏德表示respect
。
// *?!
Finders Keepers
function find(arr, func) {
var num = 0;
return arr.filter(func)[0];
}
Drop it
PS: 那一段賣隊友也是很666,我表示贊同。但輔助會怎麽想?
function drop(arr, func) {
// Drop them elements.
var n = arr.shift();
if (n !== undefined) {
if (!func(n)) {
return drop(arr, func);
} else {
arr.unshift(n);
return arr;
}
} else {
return [];
}
return arr;
}
Steamroller
function steamroller(arr) {
// I‘m a steamroller, baby
var result = [], i, l;
for(i = 0, l = arr.length; i < l; i++){
if(Array.isArray(arr[i])){
result = result.concat(steamroller(arr[i]));
}else{
result.push(arr[i]);
}
}
return result;
}
Binary Agents
- 將二進制字符串參數通過
空格
切分為數組 - 將2進制轉為10進制
- 通過
String.fromCharCode
返回字符串
function binaryAgent(str) {
return str.split(/\s/g).map(function(s){
return String.fromCharCode(parseInt(s, 2));
}).join(‘‘);
}
Everything Be True
function every(collection, pre) {
// Is everyone being true?
return collection.every(function(item) {
return item[pre];
});
}
Arguments Optional
函數curry化參考JavaScript currying
function add(a, b) {
var args = Array.prototype.slice.call(arguments, 0);
if (typeof a !== ‘number‘) return undefined;
if (args.length < 2) {
return function (b) {
if (typeof b !== ‘number‘) return undefined;
args.push(b);
return add.apply(this, args);
};
} else {
if (typeof b !== ‘number‘) return undefined;
}
return a + b;
}
結語
不算上我做題的時間,我就是復制自己寫好的代碼也花了一段時間。而且部分題目沒有被 freeCodeCamp 記錄了,又重新來一次,但只有前幾道是。應該是間隔一段時間後,數據會被清掉而只記錄是否完成狀態。
表示這個 Smallest Common Multiple 我寫的遞歸未過,所以不貼。
感謝上面貼出的所有引用連接,如果有任何引用存在問題,請聯系作者立即下線。
觀看容易,手打不易,且看且學習。
FreeCodeCamp( FCC)前端工程師 中級算法練習 分析與解答(全)(精)