Ruby 算法删除元音,意外结果

Ruby 算法删除元音,意外结果,ruby,string,Ruby,String,我正在尝试构建一个算法,从字符串中删除元音。下面的代码是我到目前为止的代码 def shortcut(s) s = s.split("") for i in 0..s.length - 1 do if ["a","e","i","o","u"].include?(s[i]) s.delete_at(i) end end s.join end puts shortcut("hello world, we are the champions") # =

我正在尝试构建一个算法,从字符串中删除元音。下面的代码是我到目前为止的代码

def shortcut(s)
  s = s.split("")
  for i in 0..s.length - 1 do
    if ["a","e","i","o","u"].include?(s[i])
      s.delete_at(i)
    end
  end
  s.join
end


puts shortcut("hello world, we are the champions")
# => hll wrld, w r th chmpons

为什么没有从字符串中删除
'o'

在对数组进行迭代时,正在从数组
s
中删除元素。这会给你带来意想不到的结果

改用:


通过删除字符,索引将无效

hello
  ^    before delete
01234
  v    after delete
hllo
您可以从头到脚迭代来解决它

def shortcut(s)
  s = s.split("")
  (s.length - 1).downto(0) do |i|
    if ["a","e","i","o","u"].include?(s[i])
      s.delete_at(i)
    end
  end
  s.join
end
但更好的解决方案是使用字符串替换方法,如


在从数组中删除元素时,迭代器i可以大于数组末尾之前的大小。

您的方法可以是

def shortcut(s)
  s = s.split("")
  for i in 0..s.length - 1 do
    s.delete(s[i]) if ["a","e","i","o","u"].include? s[i]
  end
  s.join
end


> shortcut("hello world, we are the champions")
=> "hll wrld, w r th chmpns"
另一种方式

> s = "hello world, we are the champions"
> (s.split("") - s.scan(/[aeiou]/)).join
=> "hll wrld, w r th chmpns"
最短路径

def shortcut(s)
  s.gsub(/[aeiou]/i, '')
end

shortcut('hello world, we are the champions')
#=> "hll wrld, w r th chmpns"
您也可以使用


如果研究以下简化示例,您将理解为什么删除要迭代的数组的元素会导致获得的结果

s = "two lions"
s = s.split("")
puts "s.split=#{s}"
for i in 0..s.length - 1 do
  puts "i=#{i}"
  str = s[i]
  puts "  str=/#{str}/"
  if ["a","e","i","o","u"].include?(s[i])
    puts "  str is a vowel"
    s.delete_at(i)
    puts "  s after delete_at(#{i})=#{s}"
  end
end
puts "s after loop=#{s}"
puts "s.join=#{s.join}"
s.join
印刷品

s.split=["t", "w", "o", " ", "l", "i", "o", "n", "s"]
i=0
  str=/t/
i=1
  str=/w/
i=2
  str=/o/
  str is a vowel
  s after delete_at(2)=["t", "w", " ", "l", "i", "o", "n", "s"]
跳过该空间

i=3
  str=/l/
i=4
  str=/i/
  str is a vowel
  s after delete_at(4)=["t", "w", " ", "l", "o", "n", "s"]
“o”现在位于索引4,“n”位于索引5

i=5
  str=/n/
i=6
  str=/s/
i=7
  str=//
i=8
  str=//
s after loop=["t", "w", " ", "l", "o", "n", "s"]
s.join=tw lons

我很感激你给我展示了解决这个问题的新方法。这很好,现在我知道如何用不同的方式来做了。但这仍然不能解释为什么我会得到意外的结果。@TodLazarov原因是我的第一句话:你在迭代数组时从数组
s
中删除元素。@YuHao严格地说,结果是预期的:实际字符串的第n个字母。这是正确的:)感谢您花时间回答我的问题。
compact
在这里完全没有意义,除非您期望二进制输入,否则您的解决方案无论如何都会失败。谢谢!我学到了一种新方法:)即使在这种情况下它不起作用。
s.split=["t", "w", "o", " ", "l", "i", "o", "n", "s"]
i=0
  str=/t/
i=1
  str=/w/
i=2
  str=/o/
  str is a vowel
  s after delete_at(2)=["t", "w", " ", "l", "i", "o", "n", "s"]
i=3
  str=/l/
i=4
  str=/i/
  str is a vowel
  s after delete_at(4)=["t", "w", " ", "l", "o", "n", "s"]
i=5
  str=/n/
i=6
  str=/s/
i=7
  str=//
i=8
  str=//
s after loop=["t", "w", " ", "l", "o", "n", "s"]
s.join=tw lons