用ruby计算字符串中的元音

用ruby计算字符串中的元音,ruby,iteration,Ruby,Iteration,我的目标是返回给定字符串中元音的数量。我尝试过以下代码: def count_vowels(string) vowels = ['a', 'e', 'i', 'o', 'u'] chars_ary = string.split(//) ary_with_vowels = chars_ary.take_while {|letter| vowels.include?(letter)} return ary_with_vowels.length end 而且它不能通过大多数测试用例。

我的目标是返回给定字符串中元音的数量。我尝试过以下代码:

def count_vowels(string)
  vowels = ['a', 'e', 'i', 'o', 'u']
  chars_ary = string.split(//)
  ary_with_vowels = chars_ary.take_while {|letter| vowels.include?(letter)}
  return ary_with_vowels.length
end
而且它不能通过大多数测试用例。我知道还有很多其他方法可以解决这个问题,但我想用我提供的代码来解决它

有人能告诉我为什么这个方法不起作用吗?

take\u while是错误的方法。它从开头开始,只要块返回truthy值,就接受元素。当你第一次遇到一个不是元音的字母时,它就会停止

您需要选择该选项,该选项选择块返回真实值的所有元素。

take\u while是错误的方法。它从开头开始,只要块返回truthy值,就接受元素。当你第一次遇到一个不是元音的字母时,它就会停止


您需要选择块返回真实值的所有元素。

尝试类似的方法,查看元音数组中的每个字符,并将其与字符串中的每个字符进行比较,如果条件为真,则p it

def vowles(string)
arr = []
vowels = %w(a e i o u)
vowels.each do |x|
    if string.each_char { |letter| (arr << x) if x == letter }
    end
  end
  p "#{arr} has #{arr.count} vowels"
end
vowles("wwwweeeeeee")

试着这样做,它查看元音数组中的每个字符,并将其与字符串中的每个字符进行比较,如果条件为true,则将其与p进行比较

def vowles(string)
arr = []
vowels = %w(a e i o u)
vowels.each do |x|
    if string.each_char { |letter| (arr << x) if x == letter }
    end
  end
  p "#{arr} has #{arr.count} vowels"
end
vowles("wwwweeeeeee")
这样更容易:

 def count_vowels(string)
   string.count('aeiou')
 end
这样更容易:

 def count_vowels(string)
   string.count('aeiou')
 end

让我们对一些方法进行基准测试

require 'fruity'
require 'set'

SET_OF_VOWELS = %w| a e i o u |.to_set

def string_count(str)
  str.count('aeiou')
end

def set_include?(str)
  str.each_char.count { |c| SET_OF_VOWELS.include?(c) }
end

def use_hash(str)
  h = str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
  SET_OF_VOWELS.sum { |c| h[c] }
end

alpha = ('a'..'z').to_a

[1_000, 10_000, 100_000, 1_000_000].each do |n|

  puts "\nString length = #{n}"     
  str = Array.new(n) { alpha.sample }.join

  compare(
    string_count: -> { string_count(str) },
    set_include?: -> { set_include?(str) },
    use_hash:     -> { use_hash(str) }
  )
end    
结果如下

String length = 1000
Running each test 1024 times. Test will take about 9 seconds.
string_count is faster than set_include? by 159x ± 1.0
set_include? is faster than use_hash by 37.999999999999986% ± 1.0%

String length = 10000
Running each test 128 times. Test will take about 11 seconds.
string_count is faster than set_include? by 234x ± 1.0
set_include? is faster than use_hash by 35.00000000000001% ± 1.0%

String length = 100000
Running each test 16 times. Test will take about 14 seconds.
string_count is faster than set_include? by 246x ± 1.0
set_include? is faster than use_hash by 35.00000000000001% ± 1.0%

String length = 1000000
Running each test 2 times. Test will take about 18 seconds.
string_count is faster than set_include? by 247x ± 1.0
set_include? is faster than use_hash by 34.00000000000001% ± 1.0%

让我们对一些方法进行基准测试

require 'fruity'
require 'set'

SET_OF_VOWELS = %w| a e i o u |.to_set

def string_count(str)
  str.count('aeiou')
end

def set_include?(str)
  str.each_char.count { |c| SET_OF_VOWELS.include?(c) }
end

def use_hash(str)
  h = str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
  SET_OF_VOWELS.sum { |c| h[c] }
end

alpha = ('a'..'z').to_a

[1_000, 10_000, 100_000, 1_000_000].each do |n|

  puts "\nString length = #{n}"     
  str = Array.new(n) { alpha.sample }.join

  compare(
    string_count: -> { string_count(str) },
    set_include?: -> { set_include?(str) },
    use_hash:     -> { use_hash(str) }
  )
end    
结果如下

String length = 1000
Running each test 1024 times. Test will take about 9 seconds.
string_count is faster than set_include? by 159x ± 1.0
set_include? is faster than use_hash by 37.999999999999986% ± 1.0%

String length = 10000
Running each test 128 times. Test will take about 11 seconds.
string_count is faster than set_include? by 234x ± 1.0
set_include? is faster than use_hash by 35.00000000000001% ± 1.0%

String length = 100000
Running each test 16 times. Test will take about 14 seconds.
string_count is faster than set_include? by 246x ± 1.0
set_include? is faster than use_hash by 35.00000000000001% ± 1.0%

String length = 1000000
Running each test 2 times. Test will take about 18 seconds.
string_count is faster than set_include? by 247x ± 1.0
set_include? is faster than use_hash by 34.00000000000001% ± 1.0%

对于哪个测试用例,它不起作用?它在测试用例中失败,其中字符串没有以“a”开头,只有“a”作为元音,因为一旦条件返回false,迭代就会中断@meagar解释得最好,我使用了错误的方法。你也没有处理大写元音的字符串。你应该做chars\u ari=string.downcase.split//你知道吗?i、 e.string.count'aeiou'我想你可以写string.scan/[aeiou]/i.size.对于哪个测试用例它不起作用?它在测试用例中失败了,因为字符串不是以'a'开头,只有'a'作为元音,因为一旦条件返回false,迭代就会中断@meagar解释得最好,我使用了错误的方法。你也没有处理大写元音的字符串。你应该做chars\u ari=string.downcase.split//你知道吗?i、 我想你可以写string.scan/[aeiou]/i.size.这绝对正确!我回到文档中阅读take_____________________________________。非常感谢。这是绝对正确的!我回到文档中阅读take_____________________________________。非常感谢。我会在那里抛出一个.downcase或将AEIOU添加到count字符串中,但这是解决一般问题的最佳解决方案。因为OP也不寻找大写元音,所以我保持这种方式。走到这一步,人们还会思考,例如,是ü或æ还是η或あ orø也应被视为元音。我不是语言学家,也不知道元音的概念到底是如何映射到整个Unicode字符集的,所以我最好把这个决定留给OP。我会在其中加入一个.downcase或将AEIOU添加到count字符串中,但这是解决一般问题的最佳方案。因为OP也不寻找大写元音,我一直这样。走到这一步,人们还会思考,例如,是ü或æ还是η或あ orø也应被视为元音。我不是语言学家,也不知道元音的概念到底是如何映射到整个Unicode字符集的,所以我最好让OP来决定。