尝试使用 Ruby while 循环查找字符串的元音

Posted

技术标签:

【中文标题】尝试使用 Ruby while 循环查找字符串的元音【英文标题】:Trying to find vowels of a string using Ruby while loops 【发布时间】:2015-01-02 09:19:48 【问题描述】:
def count_vowels(string)
  vowels = ["a", "e", "i", "o", "u"]
  i = 0
  j = 0
  count = 0

  while i < string.length do
    while j < vowels.length do
      if string[i] == vowels[j]
        count += 1
        break
      end

      j += 1
    end

    i += 1
  end

  puts count 
end

我很难发现哪里出了问题。如果这个程序遇到一个辅音,它就会停止。另外,如何使用“.each”方法解决同样的问题?

【问题讨论】:

为什么必须使用 while 循环来完成?不用一行也可以解决。 作为一个练习来帮助我理解 while 循环是如何工作的。 【参考方案1】:

问题是您从未将j 重置为零。

第一次运行外部while 循环时,即比较string 的第一个字符与每个元音,j 从 0(对于“a”)递增到 4(对于“u”) .然而,第二次外部循环运行时,j 已经是 4,这意味着它随后会递增到 5、6、7 等等。 vowels[5]vowels[6] 等都计算为 nil,因此第一个之后的字符永远不会算作元音。

如果您将j = 0 行移到外部while 循环内,则您的方法可以正常工作。


您的第二个问题是关于.each,表明您已经在正确地思考问题。 while 在 Ruby 中很少见,.each 肯定是一个改进。事实证明,您不能在 String 上调用 .each(因为 String 类不包含 Enumerable),因此您必须首先使用 String#chars 方法将其转换为字符数组。这样,您的代码将如下所示:

def count_vowels(string)
  chars = string.chars
  vowels = ["a", "e", "i", "o", "u"]
  count = 0

  chars.each do |char|
    vowels.each do |vowel|
      if char == vowel
        count += 1
        break
      end
    end
  end

  puts count
end

不过,在 Ruby 中,我们有更好的方法来做这种事情。一个特别适合这里的是Array#count。它需要一个块并为数组中的每个项目评估它,然后返回该块返回 true 的项目数。使用它我们可以编写这样的方法:

def count_vowels(string)
  chars = string.chars
  vowels = ["a", "e", "i", "o", "u"]

  count = chars.count do |char|
    is_vowel = false
    vowels.each do |vowel|
      if char == vowel
        is_vowel = true
        break
      end
    end

    is_vowel
  end

  puts count
end

不过,这并不短。我们可以使用的另一个好方法是Enumerable#any?。它为数组中的每个项目评估给定块,并在找到该块返回 true 的任何项目时返回 true。使用它使我们的代码超级短,但仍然可读:

def count_vowels(string)
  chars = string.chars
  vowels = %w[ a e i o u ]

  count = chars.count do |char|
    vowels.any? |vowel| char == vowel 
  end

  puts count
end

(在这里你会看到我引入了另一个常见的 Ruby 习语,用于创建数组的“百分比文字”表示法:%w[ a e i o u ]。这是创建字符串数组的常用方法,无需所有这些引号和逗号. 你可以read more about it here.)

做同样事情的另一种方法是使用Enumerable#include?,如果数组包含给定项,则返回true:

def count_vowels(string)
  vowels = %w[ a e i o u ]  
  puts string.chars.count |char| vowels.include?(char) 
end

...但事实证明,String 也有一个 include? 方法,所以我们可以这样做:

def count_vowels(string)
  puts string.chars.count |char| "aeiou".include?(char) 
end

还不错!但我把最好的留到了最后。 Ruby 有一个很棒的方法叫做String#count

def count_vowels(string)
  puts string.count("aeiou")
end

【讨论】:

哇——感谢乔丹,这太棒了。我是 Ruby 和大多数编程的新手,所以这给了我很多东西。 @wannabeprogrammer 很高兴为您提供帮助! 哈哈,很棒的答案!我喜欢从嵌套 while 循环到单个方法调用的进展。这就是 Ruby 的力量。 很好的教学答案。在他们所在的地方与 OP 会面,并引导他们找到一个很棒的 Ruby 风格的解决方案。

以上是关于尝试使用 Ruby while 循环查找字符串的元音的主要内容,如果未能解决你的问题,请参考以下文章

Ruby 中有“do ... while”循环吗?

有没有办法在 Ruby 中使用带有任何方法的 while 循环来执行冒泡排序算法?

Python使用while循环查找字符串索引

Ruby:如果while循环中断则放一条消息,如果while循环结束则放另一条消息

在while循环ruby中多次使用数组ELEMENT

为啥学习 Ruby 中的元编程和特征类很重要?