【问题标题】:Count Vowels in String Using Recursion With JavaScript使用 JavaScript 递归计算字符串中的元音
【发布时间】:2019-09-01 10:40:25
【问题描述】:

您好,我想了解 JavaScript 中的递归。

到目前为止我有:

function countVowels(string) {
    let vowelCount = 0;

    // if we're not at the end of the string,
    // and if the character in the string is a vowel

    if (string.length - 1 >= 0 && charAt(string.length -1) === "aeiouAEIOU") {

    //increase vowel count every time we iterate 

        countVowels(vowelCount++);
    }
    return vowelCount;
}

首先,这给我带来了问题,因为 charAt 没有定义。迭代时我还能怎么说“当前索引处的字符”?

我不能使用 for 循环 - 我必须使用递归。

其次,我在这里正确使用递归吗?

countVowels(vowelCount++);

每次调用该函数时,我都会尝试增加元音计数。

感谢您的指导。

【问题讨论】:

    标签: javascript string recursion count


    【解决方案1】:

    你犯了两个错误:

    • 你应该有三个参数stringcount(元音计数)和当前索引i
    • 您应该使用includes() 而不是将字符与"aeiouAEIOU" 进行比较

    function countVowels(string,count= 0,i=0) {
        if(!string[i]) return count
        if("aeiou".includes(string[i].toLowerCase())) count++;
        return countVowels(string,count,i+1);
    }
    console.log(countVowels("abcde")) //2

    正如 OP 在 cmets 中询问的那样 “你能解释一下为什么它是if("aeiou".includes(string[i].toLowerCase())) 而不是 if(string[i].includes("aeiou".toLowerCase()))

    所以首先我们应该知道 include 是做什么的。 includes() 检查字符串是否包含传递给它的某个子字符串。将使用该方法的字符串将是较大的字符串,传递给includes() 的值会较小。

    错了。

    "a".includes('aeiou') //checking if 'aeiou' is present in string "a"   //false
    

    正确的一个。

    "aeiou".includes('a') //checking if 'a' is present in string "aeiou"  //true
    

    【讨论】:

    • 您能解释一下为什么它是if("aeiou".includes(string[i].toLowerCase())) 而不是if (string[i].includes("aeiou".toLowerCase())) - .includes() 不会发生在现有值上吗?比如string.includes("dog")
    • string[i] 是我们正在迭代的字符。并且总是短字符串包含在大字符串中。这里小的是string[i],大的是"aeiou"
    • @HappyHands31 欲了解更多信息,请参阅developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    【解决方案2】:

    如果您有兴趣,这里有一个不跟踪索引或计数的版本,它可能会更详细地说明如何进行递归。

    function countVowels(string) {
      if (!string.length) return 0;
      return (
    "aeiou".includes(string.charAt(0).toLowerCase()) +
    countVowels(string.substr(1))
      );
    }
    
    console.log(countVowels("")); // 0
    console.log(countVowels("abcde")); // 2
    console.log(countVowels("eee")); // 3
    
    // Note that:
    
    console.log('"hello".substr(1)', "hello".substr(1)) // ello
    console.log('"hello".charAt(0)', "hello".charAt(0)) // h
    console.log('"aeiou".includes("a")', "aeiou".includes("a")) // true
    console.log('"a".includes("aeiou")', "a".includes("aeiou")) // false

    我们的基本情况是字符串为空,所以我们返回 0。

    否则,我们检查字符串中的第一个字符是否是元音(true == 1false == 0 在 javascript 中)并将其与计算下一个(小一)字符串相加。

    【讨论】:

    • 抱歉,我对尝试学习这一点感到沮丧。我希望检查字符串中是否有元音的语法是string[i].includes("aeiou".toLowerCase())。不明白为什么是"aeiou".includes(etc),但没关系。然后你有(string.charAt(0).toLowerCase()) - 这不会只检查字符串中的第一个字符吗?我看不到字符串的迭代是如何发生的?最后我只是查看了.substr() 方法,发现这将提取字符串的一部分。所以在那种情况下,我希望它从“abcde”中提取“b”?
    • @HappyHands31 我们只需要检查第一个字符,因为每次我们删除第一个字符并将其余字符发送到函数countVowels(string.substr(1))
    • @MaheerAli 哦,所以string.substr(1) 每次删除第一个字符是什么?
    • @HappyHands31 我在 sn-p 中添加了几行,以便您可以分别查看这些项目的运行情况。尝试在开发控制台或 sn-p 中播放,看看它是如何工作的。
    【解决方案3】:

    一种可能的解决方案是:

    function countVowels(string, number) {
      if (!string) return number;
      return countVowels(string.slice(1), 'aeiouAEIOU'.includes(string[0])? number + 1 : number);
    }
    
    // tests
    console.log('abc  --> ' +  countVowels('abc', 0));
    console.log('noor --> ' + countVowels('noor', 0));
    console.log('hi   --> ' + countVowels('hi', 0));
    console.log('xyz  --> ' + countVowels('xyz', 0));

    你应该像这样调用你的函数:countVowels('abc', 0)

    关于您的解决方案的说明:

    1. 您总是在函数中重置 vowelCount,这通常不适用于递归。
    2. 您将函数定义为接受字符串,但在 countVowels(vowelCount++) 中使用整数调用它;这会行为不端。
    3. 永远记住,您必须首先在递归函数中定义基本情况,以确保您将在某个时间停止并且不会生成无限循环。

    【讨论】:

      【解决方案4】:

      使用正则表达式和slice() 方法的替代 ES6 解决方案。正则表达式 test() 方法将为元音返回 true ,正如前面的回答 JavaScript 认为 true + true === 2 中所述。

      const countVowels = str => {
        return !str.length ? 0 : /[aeiou]/i.test(str[0]) + countVowels(str.slice(1));
      }
      

      【讨论】:

        猜你喜欢
        • 2012-10-04
        • 1970-01-01
        • 2021-05-19
        • 1970-01-01
        • 2013-11-15
        • 2018-04-30
        • 2020-03-15
        • 1970-01-01
        • 2013-07-21
        相关资源
        最近更新 更多