前言
偶然看到W3Cschool上有個(gè)編程挑戰(zhàn)瞧柔,里面的題目前是面向前端方面的造锅,也有一些算法和數(shù)據(jù)結(jié)構(gòu)的題在哥蔚,我花了兩天的時(shí)間把16道初級(jí)腳本算法的題完成并做一個(gè)思路分享,從中有一定的收獲深夯,題目從實(shí)際出發(fā)咕晋,需要靈活運(yùn)用各個(gè)JS對(duì)象的屬性和方法才能完成掌呜,反復(fù)的加深了我對(duì)這些方法的認(rèn)識(shí)和理解以及運(yùn)用质蕉,也鍛煉了我的邏輯思維能力殊霞。做這些題確實(shí)很有幫助绷蹲,以后有時(shí)間每天再去做一兩道中級(jí)的祝钢,最后再整理出來(lái)把我的解法和思路與大家共享。
翻轉(zhuǎn)字符串
先把字符串轉(zhuǎn)化成數(shù)組疤估,再借助數(shù)組的reverse方法翻轉(zhuǎn)數(shù)組順序铃拇,最后把數(shù)組轉(zhuǎn)化成字符串沈撞。
你的結(jié)果必須得是一個(gè)字符串
function reverseString(str) {
var arr = [];
arr = str.split("");
arr.reverse();
str = arr.join("");
return str;
}
console.log(reverseString("hello"));
知識(shí)點(diǎn):
- split() 把字符串分割為字符串?dāng)?shù)組显晶。
- reverse() 反轉(zhuǎn)數(shù)組的元素順序磷雇。
- join() 把數(shù)組轉(zhuǎn)換為字符串倦春,并返回結(jié)果尿庐。
階乘算法挑戰(zhàn)
計(jì)算一個(gè)整數(shù)的階乘
如果用字母n來(lái)代表一個(gè)整數(shù)抄瑟,階乘代表著所有小于或等于n的整數(shù)的乘積。
// //for循環(huán)
// function factorialize(num) {
// var i = 1
// var sum = 1;
// for (; i < num + 1; i++) {
// sum = sum * i;
// }
// return sum;
// }
// 遞歸實(shí)現(xiàn)
function factorialize(num) {
if (num == 1 || num == 0)
return 1;
else {
return factorialize(num - 1) * num;
}
}
console.log(factorialize(0));
回文算法挑戰(zhàn)
如果一個(gè)字符串忽略標(biāo)點(diǎn)符號(hào)惹资、大小寫和空格褪测,正著讀和反著讀一模一樣,那么這個(gè)字符串就是palindrome(回文)乖杠。
- 你需要去掉字符串多余的標(biāo)點(diǎn)符號(hào)和空格
- 然后把字符串轉(zhuǎn)化成小寫來(lái)驗(yàn)證此字符串是否為回文畏吓。
function palindrome(str) {
//傳入字符串處理
var newstr = str.replace(/[^0-9a-z]/gi, "");
newstr = newstr.toLowerCase();
// // 方法一
// //轉(zhuǎn)換成數(shù)組并進(jìn)行反向排序
// var arr = newstr.split("");
// arr.reverse();
// //把排序后的轉(zhuǎn)換為字符串進(jìn)行全等判斷
// arr = arr.join("");
// if (newstr === arr) {
// return true;
// } else {
// return false;
// }
//方法二 從字符串頭部和尾部卫漫,逐次向中間檢測(cè)
for (var i = 0, j = newstr.length - 1; i < j; i++, j--) {
//這里注意下庵佣,for循環(huán)內(nèi)部只判斷不符合要求的,
//如果循環(huán)后都沒(méi)返回false就在for外部返回true汛兜,不要在內(nèi)部直接返回true或提前出來(lái)
if (newstr.charAt(i) !== newstr.charAt(j)) {
return false;
}
}
return true;
}
console.log(palindrome("assa"));
尋找最長(zhǎng)的單詞算法挑戰(zhàn)
找到提供的句子中最長(zhǎng)的單詞,并計(jì)算它的長(zhǎng)度通今。
函數(shù)的返回值應(yīng)該是一個(gè)數(shù)字粥谬。
function findLongestWord(str) {
var arr = str.split(" "),
i = 0,
maxLengthNum = 0;
// var index = i + 1;
//方法一:復(fù)雜化方法:冒泡排序解法(直接第一個(gè)想到就是這個(gè),就順著來(lái)做了辫塌,發(fā)現(xiàn)復(fù)雜化漏策,
//只需要把數(shù)組長(zhǎng)度和最大值取出來(lái)做比較就行了)
// for (; i < arr.length - 1; i++) {
// for (; index < arr.length; index++) {
// if (arr[i].length < arr[index].length) {
// var temp = arr[i];
// arr[i] = arr[index];
// arr[index] = temp;
// }
// }
// }
// return arr[0].length;
//方法二:取出數(shù)組長(zhǎng)度值與歷史最大值比較,第一個(gè)默認(rèn)為起始最大值
for (; i < arr.length; i++) {
if (arr[i].length > maxLengthNum) {
maxLengthNum = arr[i].length;
}
}
return maxLengthNum;
}
findLongestWord("The quick brown fox jumped over the lazy dog");
設(shè)置首字母大寫算法挑戰(zhàn)
確保字符串的每個(gè)單詞首字母都大寫,其余部分小寫。
//方法一:復(fù)雜化,沒(méi)有使用charAt+replace、map() + slice()
// function titleCase(str) {
// var arr = str.toLowerCase().split(" ");
// var newArr = new Array();
// var i = 0;
// for (; i < arr.length; i++) {
// newArr[i] = arr[i].split("");
// newArr[i][0] = newArr[i][0].toUpperCase();
// newArr[i] = newArr[i].join("");
// }
// arr = newArr.join(" ");
// console.log(arr);
// return arr;
// }
//方法二:簡(jiǎn)單化用replace替換首字母大寫
// function titleCase(str) {
// var arr = str.toLowerCase().split(" ");
// var i = 0;
// for (; i < arr.length; i++) {
// var Up = arr[i].charAt(0).toUpperCase();
// arr[i] = arr[i].replace(arr[i].charAt(0), Up);
// }
// return arr.join(" ");
// }
//方法三:map() + replace()
function titleCase(str) {
var arr = str.toLowerCase().split(" ").map(function(word) {
return (word.charAt(0).toUpperCase() +
word.slice(1));
}).join(" ");
console.log(arr);
return arr;
}
titleCase("I'm a little tea pot");
尋找數(shù)組中的最大值算法挑戰(zhàn)
右邊大數(shù)組中包含了4個(gè)小數(shù)組,分別找到每個(gè)小數(shù)組中的最大值砸捏,然后把它們串聯(lián)起來(lái)掂骏,形成一個(gè)新數(shù)組田绑。
方法一:
function largestOfFour(arr) {
var i = 0,
j = 0,
maxArr = [];
for (; i < arr.length; i++) {
var max = 0; //內(nèi)部循環(huán)后民逼,比較值要清空一次映屋。
for (; j < arr[i].length; j++) {
if (arr[i][j] > max) {
max = arr[i][j];
}
}
maxArr.push(max);
}
return maxArr;
}
largestOfFour([
[13, 27, 18, 26],
[4, 5, 1, 3],
[32, 35, 37, 39],
[1000, 1001, 857, 1]
]);
方法二(提供者:沐辰樓-姬):
function largestOfFour(arr) {
var i = 0;
var maxArr =[];
for (; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
if (j===0) {
maxArr[i] = arr[i][j];
}else{
//采用Math對(duì)象的max方法取值優(yōu)化內(nèi)部循環(huán)性能
maxArr[i]=Math.max(maxArr[i],arr[i][j]);
}
}
}
return maxArr;
}
確認(rèn)末尾字符算法挑戰(zhàn)
檢查一個(gè)字符串(str)是否以指定的字符串(target)結(jié)尾。
//方法一:使用lastIndexOf從最后開(kāi)始查找,并返回對(duì)應(yīng)的起始位置到其索引,再做比較嚷往,indexOf也可實(shí)現(xiàn)返回索引
// function confirmEnding(str, target) {
// var index = str.lastIndexOf(target);
// return index == str.length - target.length;
// }
//方法二:使用substr抽取出字符趋急,用負(fù)數(shù)來(lái)實(shí)現(xiàn)從末尾抽對(duì)應(yīng)的查詢字符的長(zhǎng)度
//如果查找的字符實(shí)在最后出現(xiàn),則抽取出來(lái)的應(yīng)該和需要查找的一樣侥祭,同理slice也可以實(shí)現(xiàn)提取
function confirmEnding(str, target) {
var endingPart = str.substr(-(target.length));
return target === endingPart;
}
console.log(confirmEnding("Walking on water and developing software from a are easy if both are frozen specification", "specification"));
重復(fù)操作算法挑戰(zhàn)
重復(fù)一個(gè)指定的字符串 num次,如果num是一個(gè)負(fù)數(shù)則返回一個(gè)空字符串。
function repeat(str, num) {
var temp = str,
i = 0;
if (num < 0) {
return "";
} else {
for (; i < num - 1; i++) {
str = str.concat(temp);
}
}
return str;
}
console.log(repeat("abc", 3));
字符串截取算法挑戰(zhàn)
如果字符串的長(zhǎng)度比指定的參數(shù)num長(zhǎng)趾撵,則把多余的部分用...來(lái)表示。切記赶站,插入到字符串尾部的三個(gè)點(diǎn)號(hào)也會(huì)計(jì)入字符串的長(zhǎng)度瑟蜈。但是,如果指定的參數(shù)num小于或等于3,則添加的三個(gè)點(diǎn)號(hào)不會(huì)計(jì)入字符串的長(zhǎng)度狼讨。
function truncate(str, num) {
var more = "...";
// Clear out that junk in your trunk
if (str.length <= num) {
if (num <= 3) {
var newStr = str.substr(0, num);
str = newStr.concat(more);
} else
return str;
} else {
if (num <= 3) {
var newStr = str.substr(0, num);
str = newStr.concat(more);
} else {
var newStr = str.substr(0, num - 3);
str = newStr.concat(more);
}
}
return str;
}
console.log(truncate("Absolutely Longer", 2));
數(shù)組分割算法挑戰(zhàn)
猴子吃香蕉可是掰成好幾段來(lái)吃哦!
把一個(gè)數(shù)組arr按照指定的數(shù)組大小size分割成若干個(gè)數(shù)組塊。
例如:chunk([1,2,3,4],2)=[[1,2],[3,4]];
chunk([1,2,3,4,5],2)=[[1,2],[3,4],[5]];
function chunk(arr, size) {
// Break it up.
var newArr = [];
var index = 0,
end = size,
i = 0;
var count = arr.length / size;
console.log(count);
for (; i < count; index += size) {
newArr[i] = arr.slice(index, end);
end = end + end;
i++;
}
return newArr;
}
console.log(chunk([0, 1, 2, 3, 4, 5, 6], 3));
數(shù)組截?cái)嗨惴ㄌ魬?zhàn)
返回一個(gè)數(shù)組被截?cái)鄋個(gè)元素后還剩余的元素筝蚕,截?cái)鄰乃饕?開(kāi)始坯沪。
方法一:
function slasher(arr, howMany) {
if (arr.length > howMany) {
arr = arr.slice(-(arr.length - howMany));
return arr;
} else return [];
}
console.log(slasher([1, 2, 3], 4));
方法二:(提供者沐辰樓-姬)
function slasher(arr, howMany) {
for (var i = 0; i < howMany; i++) {
//使用數(shù)組對(duì)象shift()方法藻糖,把數(shù)組的第一個(gè)元素從其中刪除巨柒,并返回第一個(gè)元素的值禽最。
arr.shift();
}
return arr;
}
數(shù)組查詢算法挑戰(zhàn)
蛤蟆可以吃隊(duì)友疹味,也可以吃對(duì)手憎夷。
如果數(shù)組第一個(gè)字符串元素包含了第二個(gè)字符串元素的所有字符,函數(shù)返回true拾给。
舉例祥得,["hello", "Hello"]應(yīng)該返回true,因?yàn)樵诤雎源笮懙那闆r下蒋得,第二個(gè)字符串的所有字符都可以在第一個(gè)字符串找到啃沪。["hello", "hey"]應(yīng)該返回false,因?yàn)樽址?hello"并不包含字符"y"窄锅。["Alien", "line"]應(yīng)該返回true创千,因?yàn)?line"中所有字符都可以在"Alien"找到。
function mutation(arr) {
var count = 0,
newArr, i = 0;
newArr = arr.join(" ");
newArr = newArr.toLowerCase().split(" ");
newArr[0] = newArr[0].split("");
newArr[1] = newArr[1].split("");
console.log(newArr);
for (; i < newArr[1].length; i++) {
var index = 0;
for (; index < newArr[0].length; index++) {
if (newArr[1][i] == newArr[0][index]) {
count++;
index = newArr[0].length;
}
}
console.log(count);
}
return count === arr[1].length;
}
console.log(mutation(["floor", "for"]));
刪除數(shù)組中特定值算法挑戰(zhàn)
刪除數(shù)組中的所有假值入偷。
在JavaScript中追驴,假值有false、null疏之、0殿雪、""、undefined 和 NaN锋爪。
function bouncer(arr) {
var index = 0;
// Don't show a false ID to this bouncer.
for (; index < arr.length; index++) {
if (!arr[index]) {
arr.splice(index, 1);
//保證刪除數(shù)組元素后丙曙,索引不跳過(guò)下一個(gè)
index--;
}
}
return arr;
}
console.log(bouncer([7, "ate", "", false, 9]));
去除數(shù)組中任意多個(gè)值算法挑戰(zhàn)
實(shí)現(xiàn)一個(gè)摧毀(destroyer)函數(shù),第一個(gè)參數(shù)是待摧毀的數(shù)組其骄,其余的參數(shù)是待摧毀的值亏镰。
function destroyer(arr, del1, del2, del3) {
var newDel = [del1, del2, del3],
index = 0;
for (; index < newDel.length; index++) {
var i = 0;
for (; i < arr.length; i++) {
if (arr[i] == newDel[index]) {
arr.splice(i, 1);
i--;
}
}
}
return arr;
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
數(shù)組排序并插入值算法挑戰(zhàn)
先給數(shù)組排序,然后找到指定的值在數(shù)組的位置拯爽,最后返回位置對(duì)應(yīng)的索引索抓。
舉例:where([1,2,3,4], 1.5) 應(yīng)該返回 1。因?yàn)?.5插入到數(shù)組[1,2,3,4]后變成[1,1.5,2,3,4],而1.5對(duì)應(yīng)的索引值就是1逼肯。
同理耸黑,where([20,3,5], 19) 應(yīng)該返回 2。因?yàn)閿?shù)組會(huì)先排序?yàn)?[3,5,20]篮幢,19插入到數(shù)組[3,5,20]后變成[3,5,19,20]大刊,而19對(duì)應(yīng)的索引值就是2。
function where(arr, num) {
arr.push(num);
var i = 0,
index = 0;
for (; i < arr.length - 1; i++) {
var j = i + 1;
for (; j < arr.length; j++) {
if (arr[i] > arr[j]) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for (; index < arr.length; index++) {
if (arr[index] == num) {
return index;
}
}
}
console.log(where([2, 20, 10], 19));
位移密碼算法挑戰(zhàn)
下面我們來(lái)介紹風(fēng)靡全球的凱撒密碼Caesar cipher三椿,又叫移位密碼奈揍。
移位密碼也就是密碼中的字母會(huì)按照指定的數(shù)量來(lái)做移位。
一個(gè)常見(jiàn)的案例就是ROT13密碼赋续,字母會(huì)移位13個(gè)位置。由'A' ? 'N', 'B' ?'O'另患,以此類推纽乱。
寫一個(gè)ROT13函數(shù),實(shí)現(xiàn)輸入加密字符串昆箕,輸出解密字符串鸦列。
所有的字母都是大寫,不要轉(zhuǎn)化任何非字母形式的字符(例如:空格鹏倘,標(biāo)點(diǎn)符號(hào))薯嗤,遇到這些特殊字符,跳過(guò)它們纤泵。
方法一:
function rot13(str) { // LBH QVQ VG!
var arr = [];
for (var index = 0; index < str.length; index++) {
arr[index] = str.charCodeAt(index);
if (arr[index] >= 65 && arr[index] <= 77) {
arr[index] += 13;
}
//字母為26個(gè)當(dāng)在字母末13個(gè)位骆姐,右移13位不是字母,應(yīng)該進(jìn)行左移捏题、保證在字母26位里玻褪。
else if (arr[index] > 77 && arr[index] < 91)
arr[index] -= 13;
}
for (var i = 0; i < arr.length; i++) {
arr[i] = String.fromCharCode(arr[i]);
}
return arr.join("");
}
// Change the inputs below to test
console.log(rot13("SERR PBQR PNZC"));
方法二(提供者:沐辰樓-姬)
function rot13(str) {
var a = [];
for (var i = 0; i <
str.length; i++) {
a[i] = str.charCodeAt(i);
if (a[i] >= 65 && a[i] <= 90) {
a[i] = a[i] + 13;
//優(yōu)化處
if (a[i] > 90) {
a[i] = a[i] - 91 + 65;
}
}
}
for (var j = 0; j <
a.length; j++) {
a[j] = String.fromCharCode(a[j]);
}
return a.join("");
}
End
大家如果有更好的方法或者其他解法歡迎補(bǔ)充和交流,可與我直接聯(lián)系公荧。