发布于 2026-01-06 3 阅读
0

JavaScript 算法挑战 | 第二部分 前提条件 挑战 1 — 最大字符数 挑战 2 — Fizzbuzz 结语 Martin Nordström

JavaScript 算法挑战 | 第二部分

先决条件

挑战 1 — 最大角色

挑战 2 — Fizzbuzz

最后发言

马丁·诺德斯特伦

嗨,又见面了!

这是我的 JavaScript 编程挑战的第二部分,我非常兴奋能开始挑战。我要感谢大家对我第一篇文章的友好反馈,尤其要感谢 Dev.to 团队在他们的 Twitter 上推荐了我的文章!

如果你还没看过第一篇,可以点击这里:JavaScript 算法挑战 | 第一部分

现在让我们开始迎接挑战吧!:-)

先决条件

我将使用 Node.js 来运行 Javascript 代码,所以请您在继续之前安装它。

我已经为本文创建了一些入门代码,方便您快速上手!代码如下:

/*
Author: Martin Nordström
Created: 2018/04/07 
Keep coding!
*/

// MAX CHARACTER CHALLENGE
// Return the character that is most common in a string
function maxCharacter(str) {}

// FIZZBUZZ CHALLENGE
// Write a program that prints all the numbers from 1 to 100. For multiples of 3, instead of the number, print "Fizz", for multiples of 5 print "Buzz". For numbers which are multiples of both 3 and 5, print "FizzBuzz".
function fizzBuzz() {}
Enter fullscreen mode Exit fullscreen mode

安装好 Node.js 并准备好启动代码后,就可以开始使用了!:-)

挑战 1 — 最大角色

解决这个问题有很多不同的方法。我想向你展示一种比较复杂的方法,但我相信如果你在面试中遇到这类问题,这种方法能很好地提升你的技能并展现你的能力。

我们需要做的是显示字符串中出现频率最高的字符。例如:

maxCharacter('lollipop') == 'l'

如您所见,字符串中最常用的字符lollipop是句点l

我们首先要创建一个映射对象。所以我们将创建一个空对象。

function maxCharacter(str) {
  const charMap = {};
}
Enter fullscreen mode Exit fullscreen mode

之后,我们需要遍历字符串数组。首先,我们使用split()方法将字符串转换为数组,然后使用forEach()循环遍历数组中的每个索引。请注意,我们需要提供forEach()一个函数,以便在每次迭代时调用该函数。

function maxCharacter(str) {
  const charMap = {};

  str.split('').forEach((char) => {

  });
}
Enter fullscreen mode Exit fullscreen mode

我们需要遍历每个键值对,因为键值对包含的是实际字符及其个数。如果键存在,我们就将其值加 1,以便找出最大的字符。如果尚未找到任何字符(例如字符串的第一个字符),我们也将其值加 1。

function maxCharacter(str) {
  const charMap = {};

  str.split('').forEach((char) => {
    if (charMap[char]) {
      charMap[char]++; // This will add 1
   } else { // If no letter has been found yet
       charMap[char] = 1;
      }
  });
}
Enter fullscreen mode Exit fullscreen mode

如果我们尝试使用该字符串运行此函数,lollipop将会得到:

{ l: 3, o: 2, i: 1, p: 2 }

正如你所看到的,它确实会注意到字符串中最常用的字符!l在本例中就是这个字符。

对了!我是这样调用这个函数的:

const output = maxCharacter('lollipop');

console.log(output);
Enter fullscreen mode Exit fullscreen mode

如果我不这样做就行不通,如果你知道原因,请告诉我!

现在我们需要返回字符串中出现次数最多的字符。为此,我将使用 `for`for in loop循环遍历对象,而不是数组。我们还要添加两个变量`x`maxCharmaxNum`y`。它们的值都将为“无”,即空字符串和 0。`x` 将maxChar代表出现次数最多的字符的实际数字,而`y`maxNum的值将等于该数字。因此,`x` 的值lollipop maxNum将为 2,`y` 的maxChar值将为 0 l

let我还应该说明,我们将使用 `with`而不是 `not`来创建变量,const因为变量的值会发生变化。

我们可以用 if 语句来检查这一点:

for (let char in charMap) {
  if (charMap[char] > maxNum) {
    maxNum = charMap[char];
    maxChar = char;
  }
}
Enter fullscreen mode Exit fullscreen mode

这里我们检查键是否大于maxNum(这将是第一次迭代)。所以我们会将设置maxNum为实际值,然后将设置maxChar为实际字符。最后直接返回maxChar

我们将拥有的是这样的:

function maxCharacter(str) {
  const charMap = {};
  let maxNum = 0;
  let maxChar = '';

  str.split('').forEach((char) => {
    if (charMap[char]) {
      charMap[char]++; // This will add 1
   } else { // If no letter has been found yet
       charMap[char] = 1;
      }
  });

  for (let char in charMap) {
    if (charMap[char] > maxNum) {
      maxNum = charMap[char];
      maxChar = char;
    }
  }
  return maxChar;
}

const output = maxCharacter('lollipop');

console.log(output); // Gives us l in this case
Enter fullscreen mode Exit fullscreen mode

恭喜!你现在知道如何用 Javascript 检查字符串中最常见的字符了!

挑战 2 — Fizzbuzz

本文的最后一个挑战题很常见,你可能听说过。它在面试和学校课程中都非常流行。例如,我曾经在编程课上用 C++ 做过一道类似的题。

我们首先要创建一个 for 循环。在这个 for 循环中,我们将一个变量设置为 1,并规定只要该变量小于或等于 100,循环就会继续进行。最后,我们还要递增该变量的值。

function fizzBuzz() {
  for (let i = 1; i <= 100; i++) {
    console.log(i) // 1,2,3,4,5,6,7,8....100
  }
}
Enter fullscreen mode Exit fullscreen mode

我们希望实现的是:每当数字是 3 的倍数(3、6、9、12 等)时,就打印单词“” fizz。每当数字是 5 的倍数(5、10、15、20 等)时,就打印单词“” buzz。每当这两个数字的倍数相同时,例如 15,就打印单词“” fizzbuzz

如果你知道如何使用取模运算符,就可以很快很轻松地解决这个问题。

我们将创建一个如下所示的if语句:

if (i % 3 === 0) {
  console.log('fizz');
} else {
  console.log(i);
}
Enter fullscreen mode Exit fullscreen mode

取模运算只会给出余数,如果没有余数,则表示它是倍数。否则,我们将直接输出该数。运行此代码后,我们将得到以下输出:

1
2
fizz
4
5
fizz
7
8
fizz
10
11
fizz
Enter fullscreen mode Exit fullscreen mode

正如你所看到的,没有 3、6、9 等等!

对于数字 5,我们可以直接在 if 语句内部创建一个 else if 语句,并将这里的 3 替换为 5。就像这样:


if (i % 3 === 0) {
console.log('Fizz');
} else if (i % 5 === 0) {
console.log('Buzz');
} else {
console.log(i);
}

这将给我们带来:


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz // Gotta fix this!!

它能用了!但是我们需要修复一个问题:当数字同时出现 3 和 5 的倍数时,我们希望打印出“FizzBu​​zz”。正如你所看到的,数字 15 被打印成了“Fizz”,这可不行。

我们可以将当前的 if 语句改为 else if 语句,因为我们想先检查是否存在任何“FizzBu​​zz”号码。

`
if (i % 3 === 0 && i % 5 === 0) {
console.log('FizzBu​​zz');
} else if (i % 3 === 0) {
console.log('Fizz');
} else if (i % 5 === 0) {
console.log('Buzz');
} else {
console.log(i);
}

`

这将使我们:


1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

就这样!你已经完成了著名的FizzBu​​zz挑战!


if (i % 3 === 0 && i % 5 === 0)另外,你可以用if (i % 15 === 0)
“因为如果是 15 的倍数,它就是 3 和 5 的倍数”来稍微简化一下。

最后发言

感谢您阅读我的“JavaScript算法挑战”系列文章的第二部分。希望您能从中学习到一些新知识,并在未来加以运用!我会努力寻找更多有趣且富有启发性的挑战。请关注我的博客或其他社交媒体平台,以便及时获取最新文章信息!

马丁·诺德斯特伦

Instagram | Twitter | Github

文章来源:https://dev.to/martinnrdstrm/javascript-algorithms-challenges--part-2-344e