前言
W3Cschool上有個編程挑戰,里面的題目前是面向前端方面的,也有一些算法和數據結構的題在,最近忙于實習,已經很久沒做了,前后隔了一個月,在公司沒事的時候又重新做了起來,索性花了2天把剩下的一起做完了。在此做下代碼思路的記錄。
區間求值算法挑戰
我們會傳遞給你一個包含兩個數字的數組。返回這兩個數字和它們之間所有數字的和。
最小的數字并非總在最前面。
function sumAll(arr) {
return (arr[0] + arr[1]) * (Math.abs(arr[0] - arr[1]) + 1) / 2;
}
console.log(sumAll([1, 4]));
找出數組間差異算法挑戰
比較兩個數組,然后返回一個新數組,該數組的元素為兩個給定數組中所有獨有的數組元素。換言之,返回兩個數組的差異。
//map或forEach數組方法
var diff = function(arr1, arr2) {
var diff = [];
arr1.map(function(val1) {
if (arr2.indexOf(val1) < 0) {
diff.push(val1);
} else {
arr2.splice(arr2.indexOf(val1), 1);
}
});
return diff.concat(arr2);
};
//傳統for循環
// var diff = function(arr1, arr2) {
// var diff = [];
// for (var i = 0; i < arr1.length; i++) {
// if (arr2.indexOf(arr1[i]) < 0) {
// diff.push(arr1[i]);
// } else {
// arr2.splice(arr2.indexOf(arr1[i]), 1);
// }
// }
// return diff.concat(arr2);
// };
console.log(diff([1, 2, 3, 6, 5], [1, 2, 3, 4, 5]));
數字轉羅馬數字
將給定的數字轉換成羅馬數字。
所有返回的 羅馬數字 都應該是大寫形式。
代碼的關鍵在于lookup對象里面的鍵值對,都是1,4,5,9這幾個數字進位。 看圖更容易明白。
function convert(num) {
var lookup ={M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
var romanStr = "";
for (var i in lookup){
while (num >= lookup[i]){
romanStr+=i;
num -= lookup[i];
}
}
return romanStr;
}
convert(36);
對象搜索算法挑戰
寫一個 function,它遍歷一個對象數組(第一個參數)并返回一個包含相匹配的屬性-值對(第二個參數)的所有對象的數組。如果返回的數組中包含 source 對象的屬性-值對,那么此對象的每一個屬性-值對都必須存在于 collection 的對象中。
例如,如果第一個參數是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }],第二個參數是 { last: "Capulet" },那么你必須從數組(第一個參數)返回其中的第三個對象,因為它包含了作為第二個參數傳遞的屬性-值對。
function where(collection, source) {
var arr = [],
index = 0; // What's in a name?
// console.log(Object.getOwnPropertyNames(source).length); //獲取對象屬性個數
for (; index < collection.length; index++) {
for (var key in collection[index]) {
var count = 0;
for (var key2 in source) {
if (collection[index].hasOwnProperty(key2)) {
if (source[key2] == collection[index][key2]) {
count++;
}
if (count == Object.getOwnPropertyNames(source).length && key == key2) {
arr.push(collection[index]);
}
}
}
}
}
return arr;
}
查詢替換算法挑戰
使用給定的參數對句子執行一次查找和替換,然后返回新句子。
第一個參數是將要對其執行查找和替換的句子。
第二個參數是將被替換掉的單詞(替換前的單詞)。
第三個參數用于替換第二個參數(替換后的單詞)。
注意:替換時保持原單詞的大小寫。例如,如果你想用單詞 "dog" 替換單詞 "Book" ,你應該替換成 "Dog"。
function myReplace(str, before, after) {
var newBefore = before.split(""),
newAfter = after.split(""),
upindex = [],
i = 0,
index = 0;
for (; i < newBefore.length; i++) {
if (newBefore[i] > 'A' && newBefore[i] < 'Z') {
upindex.push(i);
}
}
for (; index < upindex.length; index++) {
if (newAfter[upindex[index]]) {
newAfter[upindex[index]] = newAfter[upindex[index]].toString().toUpperCase();
}
}
return str.replace(before, newAfter.join(""));
}
字符串移動插入算法挑戰
把指定的字符串翻譯成 pig latin。
Pig Latin 把一個英文單詞的第一個輔音或輔音叢(consonant cluster)移到詞尾,然后加上后綴 "ay"。
如果單詞以元音開始,你只需要在詞尾添加 "way" 就可以了。
function translate(str) {
var a = str.search(/[aeiou]/);
var str2 = str;
if (a === 0) {
str2 += "way";
} else {
str2 = str.substr(a);
str2 += str.substr(0, a);
str2 += "ay";
}
return str2;
}
translate("consonant");
字符配對算法挑戰
DNA 鏈缺少配對的堿基。依據每一個堿基,為其找到配對的堿基,然后將結果作為第二個數組返回。
Base pairs(堿基對) 是一對 AT 和 CG,為給定的字母匹配缺失的堿基。
在每一個數組中將給定的字母作為第一個堿基返回。
例如,對于輸入的 GCG,相應地返回 [["G", "C"], ["C","G"],["G", "C"]]
字母和與之配對的字母在一個數組內,然后所有數組再被組織起來封裝進一個數組。
function pair(str) {
var arr = new Array();
str = str.split("");
for (var index = 0; index < str.length; index++) {
arr[index] = new Array();
arr[index].push(str[index]);
if (str[index] == "G" || str[index] == "C") {
(arr[index] == "G") ? arr[index].push(
"C"): arr[index].push("G");
} else {
(arr[index] == "A") ? arr[index].push("T"): arr[index].push("A");
}
}
return arr;
}
字符串查詢補充算法挑戰
從傳遞進來的字母序列中找到缺失的字母并返回它。
如果所有字母都在序列中,返回 undefined。
function fearNotLetter(str) {
var sub;
for (var index = 0; index < str.length - 1; index++) {
sub = str.charCodeAt(index + 1) - str.charCodeAt(index);
if (sub == 1) {
if (index == str.length) {
return undefined;
}
} else {
return String.fromCharCode(str.charCodeAt(index) + 1);
}
}
}
輸入檢查算法挑戰
檢查一個值是否是基本布爾類型,并返回 true 或 false。
基本布爾類型即 true 和 false。
function boo(bool) {
if (bool === true || bool ===false){
return true;
}
return false;
}
數組去重算法挑戰
寫一個 function,傳入兩個或兩個以上的數組,返回一個以給定的原始數組排序的不包含重復值的新數組。
換句話說,所有數組中的所有值都應該以原始順序被包含在內,但是在最終的數組中不包含重復值。
非重復的數字應該以它們原始的順序排序,但最終的數組不應該以數字順序排序。
function unite(arr1, arr2, arr3, arr4) {
var arr = [],
result = [],
index = 0;
if (arr4) {
arr = arr1.concat(arr2, arr3, arr4);
} else if (arr3) {
arr = arr1.concat(arr2, arr3);
} else {
arr = arr1.concat(arr2);
}
for (; index < arr.length; index++) {
if (result.indexOf(arr[index]) == -1) {
result.push(arr[index]);
}
}
return result;
}
es6實現
//ES6新增的Set數據結構,類似于數組,但是里面的元素都是唯一的 ,其構造函數可以接受一個數組作為參數
//let arr=[1,2,1,2,6,3,5,69,66,7,2,1,4,3,6,8,9663,8]
//let set = new Set(array);
//{1,2,6,3,5,69,66,7,4,8,9663}
//ES6中Array新增了一個靜態方法from,可以把類似數組的對象轉換為數組
//Array.from(set)
//[1,2,6,3,5,69,66,7,4,8,9663]
function removeRepeatArray(arr){
return Array.from(new Set(arr))
}
html符號轉實體算法挑戰
將字符串中的字符 &、<、>、" (雙引號), 以及 ' (單引號)轉換為它們對應的 HTML 實體。
function convert(str) {
return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''');
}
convert("Dolce & Gabbana");
數組平鋪算法挑戰
對嵌套的數組進行平鋪嵌套數組。你必須考慮到不同層級的嵌套。
function steamroller(arr) {
// I'm a steamroller, baby
return arr.reduce(function (acc, val) {
return acc.concat(Array.isArray(val) ? (val.length > 0 ? steamroller(val) : []) : val);
}, []);
}
steamroller([1, [2], [3, [[4]]]]);
二進制轉字符算法挑戰
傳入二進制字符串,翻譯成英語句子并返回。
二進制字符串是以空格分隔的。
function binaryAgent(str) {
var arg = str.split(" ");
var temp, i;
var newArg = new Array();
for (i = 0; i < arg.length; i++) {
temp = String.fromCharCode(parseInt(arg[i], 2));
newArg.push(temp);
}
return newArg.join("");
}
console.log(binaryAgent(
"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111"
));
數組元素判斷算法挑戰
完善編輯器中的every函數,如果集合(collection)中的所有對象都存在對應的屬性(第二個參數),并且屬性(第二個參數)對應的值為真。函數返回ture。反之,返回false。
記?。耗梢酝ㄟ^點符號或[]符號來訪問對象屬性。
function every(collection, pre) {
// Is everyone being true?
function check(element, index, array) {
return element[pre];
}
if (collection.every(check)) {
return true;
} else return false;
}
函數迭代可選參數算法挑戰
創建一個計算兩個參數之和的 function。如果只有一個參數,則返回一個 function,該 function 請求一個參數然后返回求和的結果。
例如,add(2, 3) 應該返回 5,而 add(2) 應該返回一個 function。
調用這個有一個參數的返回的 function,返回求和的結果:
var sumTwoAnd = add(2);
sumTwoAnd(3) 返回 5。
如果兩個參數都不是有效的數字,則返回 undefined。
<!-- 應付答案解法 -->
var add = function(x, r) {
if (arguments.length == 1 && !isNaN(x)) {
return function(y) {
if (y instanceof Array) {
return undefined;
} else return x + y;
};
} else if (typeof(r) == "string" || isNaN(x)) {
return undefined;
} else return x + r;
};
<!-- 其他標準解法 -->
function add() {
var arr=[].concat(...arguments);
if( arr.some(function(ele){
return typeof ele!="number";
}) ){ //參數出現非數字類型,返回undefined
return undefined;
}
if( arr.length==2 ){
return arr[0]+arr[1];
}
return function(a){
if( typeof a != "number" ){ //同上
return undefined;
}
return a+arr[0];
};
}
注: isNaN()的參數如果不是數值型的會先自動轉換成數值型,再來判斷這個數值是不是NaN
MDN文檔節選關于isNaN
// The same effect with Number.isNaN():
function increment(x) {
if (Number.isNaN(Number(x))) x = 0;
return x + 1;
};
// In the following cases for the function's argument x,
// isNaN(x) is always false, although x is indeed not a
// number, but can be used as such in arithmetical
// expressions
increment(""); // 1: "" is converted to 0
increment(new String()); // 1: String object representing an empty string is converted to 0
increment([]); // 1: [] is converted to 0
increment(new Array()); // 1: Array object representing an empty array is converted to 0
increment("0"); // 1: "0" is converted to 0
increment("1"); // 2: "1" is converted to 1
increment("0.1"); // 1.1: "0.1" is converted to 0.1
increment("Infinity"); // Infinity: "Infinity" is converted to Infinity
increment(null); // 1: null is converted to 0
increment(false); // 1: false is converted to 0
increment(true); // 2: true is converted to 1
increment(new Date()); // returns current date/time in milliseconds plus 1
End
文中省略了一些題目的答案,因為偏基礎和比較簡單,我就略過了。如果大家有es6標準下或其他的一些解法思路,也可以跟我討論。