JavaScript算法【入门】

简介: JavaScript算法【入门】



基础算法

算法是描述如何处理某个问题的一系列步骤

要写一个有效的算法,你需要先将一个特定的问题分解为小的部分,并仔细思考如何用代码解决每个部分。

在这个课程中,你将通过编写算法来实现诸如转换温度、处理复杂的二维数组等,来学习算法思维的基础知识。

反转字符串

反转提供的字符串并返回反转后的字符串。

例如, “hello” 应该变成 “olleh”。

function reverseString(str) {
  return str
    .split("")
    .reverse()
    .join("");
}

Code Explanation

Our goal is to take the input, str, and return it in reverse. Our first step is to split the string by characters using split(''). Notice that we don’t leave anything in between the single quotes, this tells the function to split the string by each character.

Using the split() function will turn our string into an array of characters, keep that in mind as we move forward.

Next we chain the reverse() function, which takes our array of characters and reverses them.

Finally, we chain join('') to put our characters back together into a string. Notice once again that we left no spaces in the argument for join, this makes sure that the array of characters is joined back together by each character.

计算整数的阶乘

返回一个给定整数的阶乘计算结果。

对于整数 n,n 的阶乘就是所有小于等于 n 的正整数的乘积。

阶乘通常用符号 n! 来表示。

例如:5! = 1 * 2 * 3 * 4 * 5 = 120

在这个挑战中,只有非负整数会作为参数传入函数。

function factorialize(num) {
  let mp=1;
  for(let i=1;i<=num;i++){
      mp*=i
  }
  return mp;
}
factorialize(5);

找出字符串中的最长单词

返回给出的句子中,最长单词的长度。

函数的返回值应是一个数字。

function findLongestWordLength(str) {
  return Math.max(...str.split(" ").map(word=>word.length))
}
console.log(findLongestWordLength("The quick brown fox jumped over the lazy dog"));

找出多个数组中的最大数字

请返回一个数组,该数组由参数中每个子数组中的最大数字组成。 为简单起见,给出的数组总会包含 4 个子数组。

别忘了,你可以通过 for 循环遍历一个数组,并用 arr[i] 的写法来访问数组中的元素。

function largestOfFour(arr) {
  let cc=[]
  for(let i=0; i<arr.length; i++){
    cc.push(Math.max(...arr[i]));
  }
  return cc;
}
console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));

确认结尾

检查字符串(第一个参数 str)是否以给定的目标字符串(第二个参数 target)结束。

这个挑战 可以 用 ES2015 引入的 .endsWith() 方法来解决。但在这个挑战中,请使用 JavaScript 的字符串子串方法。

function confirmEnding(str, target) {
  return str.slice(-target.length)===target;
}
confirmEnding("Bastian", "n");

Slice用法

基本用法

我们的前4个例子突出 slice 的核心功能。

用法1:简单的复制

const arr2 = arr.slice()

没有任何参数的 slice 执行一个简单的浅拷贝。当前,主流的用法还是使用展开运算符合来实现,但是如果在旧的代码库中,或者没有使用 babel 的构建步骤,可能仍然希望使用 slice 。

用法2:获取从 N 开始的子数组

使用 slice 方法最简单的方法就是原始数组从 N 开始抽取的所有元素。

一种情况是希望弹出数组的第一个元素并使用它,返回剩余的数组,但希望在不修改原始数组的情况下执行此操作。

function useone (arr) {
  const usedItem = arr[0]
  return arr.slice(1)
}

用法3:获取从末尾 N 开始的子数组

slice 的另一种使用方法是获取数组的末尾,利用的是 负索引 从末尾开始计数。

这种负索引使删除任意数量的元素变得超级简单。例如,如果你只想抓取3个

const last3 = arr.slice(-3)

用法4:获取数组的前n个

获取数组的前面的数,我们需要使用第二个参数: end 。

当有两个参数时, slice 方法返回一个从 begin 开始但不包括 end 的集合。

由于JavaScript数组是从 0 开始的(索引从0开始),这使得获取前N个元素变得非常简单:

const first4 = arr.slice(0, 4)

用法5:获取数组中某段子数组

如果我们想要使用 slice 从任何索引开始获取数组的一段,该怎么办?

为此,我们需要从 (begin, length) 转换为 (begin, end) 。计算逻辑很简单,我们可以定义一个简单的函数来做到这一点:

function pullSegment(arr, begin, length) {
  return arr.slice(begin, begin + length);
}

重复输出字符串

将一个给定的字符串 str(第一个参数)重复输出 num(第二个参数)次。 如果 num 不是正数,返回空字符串。 在这个挑战中,请不要使用 JavaScript 内置的 .repeat() 方法

function repeatStringNumTimes(str, num) {
  return num>0?repeatStringNumTimes(str,num-1):"";
}
repeatStringNumTimes("abc", 3);

截断字符串

如果传入的字符串(第一个参数)的长度大于传入的值(第二个参数),请在这个位置截断它, 并在后面加上 …,然后返回结果。

function truncateString(str, num) {
  return str.length>num?str.slice(0,num)+"...":str;
}
truncateString("A-tisket a-tasket A green and yellow basket", 8);

按参数过滤数组

请写一个函数来检查数组(第一个参数 arr)中的元素,并返回数组中第一个通过校验测试的元素。 其中,“通过校验测试”指的是对于数组中的一个元素 x,若 func(x) 返回的结果为 true,则校验测试通过。 如果没有元素通过测试,请返回 undefined。

function findElement(arr, func) {
  let num = 0;
  for (let i = 0; i < arr.length; i++) {
    num = arr[i];
    if (func(num)) {
      return num;
    }
  }
  return undefined;
}
findElement([1, 2, 3, 4], num => num % 2 === 0);
function findElement(arr, func) {
  return arr.find(func);
}

基本类型布尔值的检查

检查一个值是否是基本类型中的布尔值(boolean)类型。 函数应返回 true 或者 false。

基本类型中的布尔值为 true 或者 false。

function booWho(bool) {
  return typeof bool==="boolean";
}
booWho(null);

句中单词首字母大写

请将传入的字符串中,每个单词的第一个字母变成大写并返回。 注意除首字母外,其余的字符都应是小写的。

在这个挑战中,我们还需要将诸如 the 和 of 之类的连接词大写。

function titleCase(str) {
  let sa=str.split(" ");
  let wudi=[]
  for( let w in sa){
    wudi[w]=sa[w][0].toUpperCase()+sa[w].slice(1).toLowerCase()
  }
  return wudi.join(" ");
}
titleCase("I'm a little tea pot");

Slice 与 Splice

本挑战的输入参数为两个数组和一个索引值。

将第一个数组中的所有元素依次复制到第二个数组中。

请注意,你需要从第二个数组索引值为 n 的地方开始插入。

最后,请返回插入元素后的数组。 作为输入参数的两个数组在函数执行前后应保持不变。

function frankenSplice(arr1, arr2, n) {
  let local=arr2.slice(0)
  local.splice(n,0,...arr1)
  return local
}
console.log(frankenSplice([1, 2, 3], [4, 5, 6], 1))

过滤数组中的假值

从数组中移除所有假值(falsy values)。 返回一个新数组;不要改变原始数组。

JavaScript 中的假值有 false、null、0、“”、undefined、NaN。

提示:可以考虑将每个值都转换为布尔值(boolean)。

function bouncer(arr) {
  let newArr=[]
  for(let i in arr){
    if(arr[i]){
      newArr.push(arr[i])
    }
  }
  return newArr;
}
console.log(bouncer([7, "ate", "", false, 9]))

找出元素在排序后数组中的索引

数组(第一个参数)在排序后,将一个值(第二个参数)插入该数组,并使数组保持有序。返回这个新插入元素的最小索引值。 返回值应为一个数字。

例如,getIndexToIns([1,2,3,4], 1.5) 应该返回 1 因为1.5 大于 1(索引为 0)且小于 2(索引为 1)。

同样地,getIndexToIns([20,3,5], 19) 应该返回 2。 因为数组排序后会变成 [3,5,20],而 19 小于 20(索引为 2)且大于 5(索引为 1)。

function getIndexToIns(arr, num) {
  arr.sort((a, b) => a - b);
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] >= num) return i;
  }
  return arr.length;
}

sort函数

sort() 方法,有一个可选参数,必须是函数,供它调用。那么就是个回调函数咯!

回调函数的参数要有两个:第一个参数的元素肯定在第二个参数的元素前面!!!

这个方法的排序是看回调函数的返回值:

如果返回值大于 0,则位置互换。

如果返回值小于 0,则位置不变。

例子:

var arr = [9,7,2];
arr.sort(function(a,b){
    if(a>b) // 如果 a 大于 b,位置互换
        return 1;
    else //否则,位置不变
        return -1;
});
// 排序结果: 2,7,9

比较字符串

如果数组里的第一个字符串包含了第二个字符串中的所有字母,则返回 true。

例如,[“hello”, “Hello”] 应该返回 true。因为在忽略大小写的情况下,第一个字符串包含了第二个字符串里出现的所有字母。

[“hello”, “hey”] 应该返回 false。因为 hello 并不包含字符 y。

最后,[“Alien”, “line”] 应该返回 true。因为 line 中的所有字母都出现在了 Alien 中。

function mutation(arr) {
  const test = arr[1].toLowerCase();
  const target = arr[0].toLowerCase();
  for (let i = 0; i < test.length; i++) {
    if (target.indexOf(test[i]) < 0) return false;
  }
  return true;
}
function mutation(arr) {
  for(let i=0; i<arr[1].length;i++){
  if(arr[0].toLowerCase().indexOf(arr[1][i].toLowerCase())<0){
    return false
  }
  }
  return true;
}
mutation(["hello", "hey"]);
function mutation([elem1, elem2]) {
  const regex = new RegExp(`[^${elem1}]`, 'i');
  return !regex.test(elem2);
}
function mutation([elem1, elem2]) {
  const regex = new RegExp(`[^${elem1}]`, 'i');
  return !regex.test(elem2);
}

分割数组

请编写一个函数,该函数将一个数组(第一个参数)拆分成若干长度为 size(第二个参数)的子数组,并将它们作为二维数组返回。

function chunkArrayInGroups(arr, size) {
  const newArr = [];
  for (let i = 0; i < arr.length; i += size) {
    newArr.push(arr.slice(i, i + size));
  }
  return newArr;
}
console.log(chunkArrayInGroups(["a", "b", "c", "d"], 2));
function chunkArrayInGroups(arr, size) {
  const newArr = [];
  while (arr.length > 0) {
    newArr.push(arr.splice(0, size));
  }
  return newArr;
}
相关文章
|
12天前
|
机器学习/深度学习 人工智能 算法
深度学习入门:理解神经网络与反向传播算法
【9月更文挑战第20天】本文将深入浅出地介绍深度学习中的基石—神经网络,以及背后的魔法—反向传播算法。我们将通过直观的例子和简单的数学公式,带你领略这一技术的魅力。无论你是编程新手,还是有一定基础的开发者,这篇文章都将为你打开深度学习的大门,让你对神经网络的工作原理有一个清晰的认识。
|
4天前
|
JavaScript 前端开发 小程序
一小时入门Vue.js前端开发
本文是作者关于Vue.js前端开发的快速入门教程,包括结果展示、参考链接、注意事项以及常见问题的解决方法。文章提供了Vue.js的基础使用介绍,如何安装和使用cnpm,以及如何解决命令行中遇到的一些常见问题。
一小时入门Vue.js前端开发
|
2月前
|
JavaScript 算法 前端开发
JS算法必备之String常用操作方法
这篇文章详细介绍了JavaScript中字符串的基本操作,包括创建字符串、访问特定字符、字符串的拼接、位置查找、大小写转换、模式匹配、以及字符串的迭代和格式化等方法。
JS算法必备之String常用操作方法
|
2月前
|
JavaScript 算法 前端开发
JS算法必备之Array常用操作方法
这篇文章详细介绍了JavaScript中数组的创建、检测、转换、排序、操作方法以及迭代方法等,提供了数组操作的全面指南。
JS算法必备之Array常用操作方法
|
2月前
|
机器学习/深度学习 人工智能 算法
AI入门必读:Java实现常见AI算法及实际应用,有两下子!
本文全面介绍了人工智能(AI)的基础知识、操作教程、算法实现及其在实际项目中的应用。首先,从AI的概念出发,解释了AI如何使机器具备学习、思考、决策和交流的能力,并列举了日常生活中的常见应用场景,如手机助手、推荐系统、自动驾驶等。接着,详细介绍了AI在提高效率、增强用户体验、促进技术创新和解决复杂问题等方面的显著作用,同时展望了AI的未来发展趋势,包括自我学习能力的提升、人机协作的增强、伦理法规的完善以及行业垂直化应用的拓展等...
159 3
AI入门必读:Java实现常见AI算法及实际应用,有两下子!
|
2月前
|
JavaScript API 图形学
一个案例带你从零入门Three.js,深度好文!
【8月更文挑战第1天】本教程无需任何Threejs知识!本教程以入门为主,带你快速了解Three.js开发
69 2
一个案例带你从零入门Three.js,深度好文!
|
2月前
|
JavaScript 算法 前端开发
"揭秘Vue.js的高效渲染秘诀:深度解析Diff算法如何让前端开发快人一步"
【8月更文挑战第20天】Vue.js是一款备受欢迎的前端框架,以其声明式的响应式数据绑定和组件化开发著称。在Vue中,Diff算法是核心之一,它高效计算虚拟DOM更新时所需的最小实际DOM变更,确保界面快速准确更新。算法通过比较新旧虚拟DOM树的同层级节点,递归检查子节点,并利用`key`属性优化列表更新。虽然存在局限性,如难以处理跨层级节点移动,但Diff算法仍是Vue高效更新机制的关键,帮助开发者构建高性能Web应用。
49 1
|
2月前
|
JavaScript 前端开发 NoSQL
使用Node.js进行后端开发入门
【8月更文挑战第10天】恭喜你完成了Node.js后端开发的入门之旅!这只是个开始,Node.js的世界远比这广阔。随着你对Node.js的深入学习和实践,你将能够构建更复杂、更强大的后端应用。不断探索、学习和实践,你将在Node.js的道路上越走越远。
|
2月前
|
Web App开发 JavaScript 前端开发
Node.js 入门
【8月更文挑战第4天】Node.js 入门
57 1
|
3月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
下一篇
无影云桌面