FCC Basic Algorithm Scripting 基础算法集

前言

本文为 FreeCodeCamp 中前端的十六道基础算法题


1. Reverse a String 翻转字符串

★ 具体步骤

  1. 字符串->数组:str.split(“连接符”)

  2. 翻转数组:arr.reverse(),本方法直接改变原数组

  3. 数组->字符串:arr.join(“连接符”)

★ 代码

function reverseString(str) {
  var arr = new Array();
  arr = str.split("");
  arr.reverse();
  str = arr.join("");
  return str;
}

reverseString("hello");  // olleh

2. Factorialize a Number 计算一个整数的阶乘

★ 具体步骤

  1. 分情况:if 判断 n=0,n>0

  2. 循环计算:n=0 时,n!=1,n>0 时,循环累乘 n!=1×2×···×n

★ 代码

function factorialize(num) {
  var sum = 1;
  if (num == 0) {
    sum = 1;
  }
  else {
    for (var i = 1; i <= num; i++) {
      sum = sum * i;
    }
  }
  return sum;
}

factorialize(5);  // 120

3. Check for Palindromes 判断回文

★ 要求

回文(palindrome):一个字符串忽略标点符号、大小写和空格,正着读和反着读一模一样,例如 eye

如果给定的字符串是回文,返回 true,反之,返回 false

★ 思路

去掉字符串多余的标点符号和空格,然后把字符串转化成小写,翻转之后检查是否与原字符串相等

★ 具体步骤

  1. 用正则表达式找到字符串多余的标点符号和空格(找出字母和数字即可)

  2. 去除非字母数字符号:str.replace(被替换部分,替换部分)

  3. 将字符串转为小写:str.toLowerCase()

  4. 将字符串翻转:见第一题

  5. 判断翻转后的字符串与原来的是否相同

正则表达式:用来匹配字符串中字符组合的模式。其中 W 表示字母、数字、下划线,因此 [\W_] 就可以表示非字母数字了,也可以用 [^A-Za-z0-9] 表示

★ 代码

function palindrome(str) {
  var re = /[\W_]/g;
  var newStr = str.replace(re,"").toLowerCase();  // 纯字母数字的小写形式
  var reverseStr = newStr.split("").reverse().join("");
  return reverseStr == newStr;
}

palindrome("eye");  // true

4. Find the Longest Word in a String 找到提供的句子中最长的单词,并计算它的长度

★ 思路

将字符串转为数组,记录下每个数组元素的长度,将长度排序

★ 具体步骤

  1. 将字符串转为数组:split()

  2. 循环:将每个数组元素的长度保存在新数组中

  3. 排序:将长度数组排序sort(),得到最大长度值

★ 代码

function findLongestWord(str) {

  var arr = new Array();
  var arrLen = new Array();
  arr = str.split(" ");

  for (var i = 0; i < arr.length; i++){
    arrLen[i] = arr[i].length;
  }

  arrLen.sort(function(a,b) {
    return b-a;
  });

  return arrLen[0];
}

findLongestWord("The quick brown fox jumped over the lazy dog");  // 6

5. Title Case a Sentence 字符串的单词首字母大写其余小写

★ 思路

先将所有字母统一为小写,再将字符串转化为数组,将每一个数组元素的第一个字符变为大写

★ 具体步骤

  1. 转小写:将字符串中所有字母转为小写 str.toLowerCase()

  2. 字符串->数组:str.split()

  3. 遍历数组,将每个数组元素第一个字母替换为大写
    遍历 arr.map()
    替换 arr.replace()
    单字符 arr.charAt(index)
    大写 toUpperCase()

  4. 数组->字符串:arr.join()

★ 代码

function titleCase(str) {

  str = str.toLowerCase();

  var arr = new Array();
  arr = str.split(" ");

  var newArr = new Array();
  newArr = arr.map(toUpper);
  function toUpper(element) {
    return element.replace(element.charAt(0),element.charAt(0).toUpperCase());
  }

  str = newArr.join(" ");
  return str;
}

titleCase("I'm a little tea pot");  // I'm A Little Tea Pot

6. Return Largest Numbers in Arrays 将小数组们的最大值串联成新数组

★ 要求

大数组中包含了若干个小数组,分别找到每个小数组中的最大值(数值的最大值),然后把它们串联起来,形成一个新数组

★ 具体步骤

  1. 先把大数组分为若干小数组

  2. 循环小数组中每一个元素

  3. 找到每个小数组中的最大值

  4. 用新数组存储最大值

★ 代码

function largestOfFour(arr) {

  var newArr = new Array();

  for (var i = 0; i < arr.length; i++) {
    var max = arr[i][0];  // max 要定义在内层循环外
    for (var j = 0; j < arr[i].length; j++) {
      if (arr[i][j] >= max) {
    max = arr[i][j];
      }
    }
    newArr[i] = max;
  }
  return newArr;
}

largestOfFour([[4,5,1,3],[13,27,18,26],[32,35,37,39],[1000,10001,857,1]]);  // [5,27,39,10001]

7. Confirm the Ending 检查一个字符串是否以指定的字符串结尾

★ 思路

首先要知道指定字符串 target 的个数,找到待检查字符串中最后几位,判断两者是否相等

★ 具体步骤

str.substr(beginindex,endindex) 方法:返回字符串从指定位置开始,到指定长度的字符串

★ 代码

function confirmEnding(str,target) {
  return target == str.substr(str.length-target.length,target.length);
}

confirmEnding("Bastian","n");  // true

8. Repeat a string repeat a string 重要的事情说3遍

★ 要求

重复一个指定的字符串 num 次,如果 num 是一个负数则返回一个空字符串

★ 具体步骤

  1. 保留原始字符串:var newStr = str

  2. 循环

★ 代码

function repeat(str,num) {
  var newStr = str;
  if (num > 0) {
    for (var i = 0; i < num; i++) {
      newStr = newStr.concat(str);
    }
  }
  else {
    newStr = "";
  }
  return newStr;
}

repeat("abc",3);  // abcabcabcabc

9. Truncate a string 用瑞兹来截断对面的退路

★ 要求

如果字符串的长度比指定的参数num长,则把多余的部分用…来表示

切记,插入到字符串尾部的三个点号也会计入字符串的长度

但是,如果指定的参数num小于或等于3,则添加的三个点号不会计入字符串的长度

★ 思路

最开始要判断 num 是否大于字符串长度,当 num 小于字符串长度时,分 num 小于等于 3 和大于 3 的情况,当 num<=3 时,直接在字符串后面加三个点;当 num> 3时,字符串 + 三个点的长度 =num

★ 具体步骤

  1. num<=3:str.slice()、str.concat(“…”)

  2. num>3:str.slice()、str.concat(“…”)

★ 代码

function truncate(str,num) {
  var newStr;
  if (num < str.length) {
    if (num <= 3) {
      newStr = str.slice(0,num);
      newStr = newStr.concat("...");
    }
    else {
      newStr = str.slice(0,num-3);
      newStr = newStr.concat("...");
    }
  }
  else {
    newStr = str;
  }
  return newStr;
}

truncate("A-tisket a-tasket A green and yellow basket","A-tisket a-tasket A green and yellow basket".length+2);  // A-tisket a-tasket A green and yellow basket

10. Chunky Monkey 猴子吃香蕉可是掰成好几段来吃哦

★ 要求

把一个数组 arr 按照指定的数组大小 size 分割成若干个数组块

★ 思路

将分割出的数组块当作一个个数组元素存在一个新的数组中,要确定分割的个数,才好循环

★ 具体步骤

设定切割起始位置 begin 与 end,并按照 size 大小累加,将切下的数组块循环 push 进新数组中

arr.slice(beginindex,endindex),切割时包括 beginindex,不包括 endindex

注意arr.push() 返回的是长度值

★ 代码

function chunk(arr,size) {

  var newArr = new Array();
  var begin = 0;
  var end = size;

  for (var i = 0; i < arr.length/size; i++) {
    newArr.push(arr.slice(begin,end));
    begin = begin + size;
    end = end + size;
  }
  return newArr;
}

chunk(["a","b","c","d","e"],2);  // [["a","b"],["c","d"]["e"]]

11. Slasher Flick 打不死的小强

★ 要求

返回一个数组被截断 n 个元素后还剩余的元素,截断从索引 0 开始(删除数组前 n 个元素)

★ 具体步骤

array.splice(start, deleteCount[, item1[, item2[, …]]])

start 为开始索引值,deleteCount 为整数,表示要移出的元素个数,item1 表示要添加的元素,若无,则函数只删除元素。函数返回被删除元素数组

★ 代码

function slasher(arr,howMany) {
  return arr.splice(howMany,arr.length-howMany);
}

slasher([1,2,3],2);  // [3]

12. Mutations 蛤蟆可以吃队友,也可以吃对手

★ 要求

如果数组第一个字符串元素包含了第二个字符串元素的所有字符,忽略顺序和大小写,函数返回 true

例如:["hello", "hey"] 应该返回 false,因为字符串 "hello" 并不包含字符 "y"
再例如:["Alien", "line"] 应该返回 true,因为 "line" 中所有字符都可以在 "Alien" 找到

★ 思路

首先要将两个字符串统一为小写,再看第二个字符串中的所有元素是不是都能在第一个字符串中找到

★ 具体步骤

  1. 数组->字符串:个数较少,直接用下标赋值

  2. 字符串转小写:str.toLowerCase()

  3. 第二个字符串->数组:str.split()

  4. 检查第二个字符串中的每个字符是否都能在第一个字符串中找到

★ 代码

function mutation(arr) {

  var str1 = arr[0].toLowerCase();
  var str2 = arr[1].toLowerCase();
  var arr2 = new Array();
  arr2 = str2.split("");

  for (var i = 0; i < arr2.length; i++) {
    if (str1.indexOf(arr2[i]) == -1) {
      return false;
    }
    else {
      continue;
    }
  }
  return true;
}

mutation(["hello","hey"]);  // false

13. Falsy Bouncer 真假美猴王

★ 要求

删除数组中的所有假值

在JavaScript中,假值有 false、null、0、”“、undefined 和 NaN

★ 思路

遍历数组,判断是否为假值,是则删除,否则留下

★ 具体步骤

  1. 遍历数组:arr.filter()

  2. 判断是否为假值:Boolean(element)。element 为假值返回 false,真值返回 true

★ 代码

function bouncer(arr) {
  var newArr = arr.fliter(delFalsy);
  function delFalsy(element) {
    return Boolean(element);
  }
  return newArr;
}

bouncer([7,"ate","",false,9]);  // [7,"ate",9]

14. Seek and Destroy 金克斯的迫击炮

★ 要求

实现一个摧毁 destroyer 函数,第一个参数是待摧毁的数组,其余的参数是待摧毁的值

例如:destroyer([1, 2, 3, 1, 2, 3], 2, 3) 应该返回 [1, 1]

★ 思路

遍历数组,将与待摧毁值相同的数组元素删除

★ 具体步骤

  1. 将待摧毁值存入一个数组中:arguments[index]

  2. 遍历数组:arr.filter()

  3. 判断是否要摧毁:循环+判断

★ 注意

  1. filter 是根据其函数返回值判断是否保留该元素,true 为保留,false 为删除。注意循环的结束与跳过情况

  2. arguments[index] 不要放在内部函数中,这样将取不到外部函数的参数

  3. 循环中最好不要调用函数

★ 代码

function destroyer() {

  var arr = arguments[0];
  var a = new Array();
  var num = arguments.length;
  var j = 0;

  for (var i = 1; i < num; i++) {
    a[j] = arguments[i];  // 待摧毁数组
    j++;
  }

  var newArr = arr.filter(destroy);
  function destroy(element) {
    for (var k = 0; k < num-1; k++) {
      var res;
      if (element == a[k]) {
        res = false;
        break;
      }
      else {
        res = true;
        continue;
      }
      return res;
    }
    return newArr;
  } 
}

destroyer([1,2,3,1,2,3],2,3);  // [1,1]

15. Where do I belong 我身在何处

★ 要求

先给数组排序,然后找到指定的值在数组的位置,最后返回位置对应的索引

例如:where([1,2,3,4], 1.5) 返回 1
因为 1.5 插入到数组 [1,2,3,4] 后变成 [1,1.5,2,3,4],而 1.5 对应的索引值就是 1

★ 具体步骤

  1. 指定元素放入数组:arr.push()

  2. 数组排序:从小到大 arr.sort()

  3. 找到指定元素的索引:arr.indexOf()

★ 代码

function where(arr,num) {
  arr.push(num);
  arr.sort(function(a,b) {
    return a-b;  // 从小到大
  });
  return arr.indexOf(num);
}

where([40,60],50);  // 1

16. Caesars Cipher 让上帝的归上帝,凯撒的归凯撒(凯撒编码)

★ 要求

写一个 ROT13 函数,实现输入加密字符串,输出解密字符串。注意:所有的字母都是大写,不要转化任何非字母形式的字符(例如:空格,标点符号),遇到这些特殊字符,跳过它们

ROT13:http://www.baike.com/wiki/ROT13&prd=so_1_doc

ROT13

★ 思路

将 A-M 的 Unicode 值 +13,将 N-Z 的 Unicode 值-13

★ 具体步骤

  1. 得到字符串中每个字母的 Unicode(UTF16) 值:str.charCodeAt(index) 返回 0~65535 之间的整数

  2. 将 A-M 的 Unicode 值 +13,将 N-Z 的 Unicode 值 -13,其余字符不变

  3. Unicode值->字母:String.fromCharCode(Unicode值)

★ 代码

function rot13(str) {
  var arr = new Array();
  for (var i = 0; i < str.length; i++) {
    var utfNum = str.charCodeAt(i);

    if (utfNum >= 65 && utfNum <= 90) {
      if (utfNum <= 77) {
        utfNum += 13;
      }
      else {
        utfNum -= 13;
      }
    }

    arr[i] = String.fromCharCode(utfNum);
  }

  str = arr.join("");
  return str;
}

rot13("SERR CVMMN!"); // "FREE PIZZA!"
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值