算法删除元音,意外结果

时间:2016-03-21 06:41:58

标签: 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")
# => hll wrld, w r th chmpons

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

7 个答案:

答案 0 :(得分:7)

删除字符后,索引将失效。

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

但更好的解决方案是使用字符串替换方法,如String#deleteString#gsub

"hello world, we are the champions".gsub(/[aeiou]/, '')
=> "hll wrld, w r th chmpns"

答案 1 :(得分:5)

您正在迭代它时从数组s中删除元素。这会给你意想不到的结果。

改为使用String#delete

"hello world, we are the champions".delete('aeiou')
# => "hll wrld, w r th chmpns" 

答案 2 :(得分:1)

当你从数组中删除元素时,你的迭代器可能会超过到达数组末尾之前的大小。

答案 3 :(得分:1)

你的方法可以

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"

答案 4 :(得分:1)

最短的方法

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

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

答案 5 :(得分:1)

您也可以使用Array#Select

def shortcut(s)
  s.chars.select{|s| s !~ /[aeiou]/ }.join('')
end

## OR

def shortcut(s)
  s.chars.select{ |s| s if !["a","e","i","o","u"].include?(s) }.join('')
end

shortcut("hello world, we are the champions")

## OUTPUT
 => "hll wrld, w r th chmpns"

答案 6 :(得分:1)

如果您学习以下简化示例,您将理解为什么删除您正在迭代的数组元素会导致您获得的结果。

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