尝试用 ruby 编写方法,将翻译猪拉丁语中的字符串,规则是:规则 1:如果单词以元音开头,请在单词末尾添加"ay"音。
规则2:如果一个单词以辅音开头,则将其移动到单词的末尾,然后在单词的末尾添加一个"ay"音,当单词以2个辅音开头时,将两个单词都移到单词的末尾并添加"ay"
作为一个新手,我的概率是第二条规则,当单词仅以一个辅音开头时它可以工作,但是对于多个辅音,我很难让它工作,有人可以查看代码并让我知道我如何以不同的方式编码,可能我的错误是什么,可能代码需要重构。谢谢,到目前为止我想出了这个代码:
def translate (str)
str1="aeiou"
str2=(/A[aeiou]/)
vowel = str1.scan(/w/)
alpha =('a'..'z').to_a
con = (alpha - vowel).join
word = str.scan(/w/)
if #first rule
str =~ str2
str + "ay"
elsif # second rule
str != str2
s = str.slice!(/^./)
str + s + "ay"
elsif
word[0.1]=~(/A[con]/)
s = str.slice!(/^../)
str + s + "ay"
else
word[0..2]=~(/A[con]/)
s = str.slice!(/^.../)
str + s + "ay"
end
end
translate("apple") 应该 == "appleay"
翻译("樱桃")应该=="Errychay"
翻译("三") 应该 == "eethray"
不需要所有这些花哨的正则表达式。保持简单。
def translate str
alpha = ('a'..'z').to_a
vowels = %w[a e i o u]
consonants = alpha - vowels
if vowels.include?(str[0])
str + 'ay'
elsif consonants.include?(str[0]) && consonants.include?(str[1])
str[2..-1] + str[0..1] + 'ay'
elsif consonants.include?(str[0])
str[1..-1] + str[0] + 'ay'
else
str # return unchanged
end
end
translate 'apple' # => "appleay"
translate 'cherry' # => "errychay"
translate 'dog' # => "ogday"
这将处理多个单词、标点符号和单词,如"queer"="eerquay"和"school"="oolschay"。
def translate (sent)
vowels = %w{a e i o u}
sent.gsub(/(A|s)w+/) do |str|
str.strip!
while not vowels.include? str[0] or (str[0] == 'u' and str[-1] == 'q')
str += str[0]
str = str[1..-1]
end
str = ' ' + str + 'ay'
end.strip
end
史诗般的猪拉丁语翻译器,我相信可以使用一些重构,但通过了测试
def translate(sent)
sent = sent.downcase
vowels = ['a', 'e', 'i', 'o', 'u']
words = sent.split(' ')
result = []
words.each_with_index do |word, i|
translation = ''
qu = false
if vowels.include? word[0]
translation = word + 'ay'
result.push(translation)
else
word = word.split('')
count = 0
word.each_with_index do |char, index|
if vowels.include? char
# handle words that start with 'qu'
if char == 'u' and translation[-1] == 'q'
qu = true
translation = words[i][count + 1..words[i].length] + translation + 'uay'
result.push(translation)
next
end
break
else
# handle words with 'qu' in middle
if char == 'q' and word[i+1] == 'u'
qu = true
translation = words[i][count + 2..words[i].length] + 'quay'
result.push(translation)
next
else
translation += char
end
count += 1
end
end
# translation of consonant words without qu
if not qu
translation = words[i][count..words[i].length] + translation + 'ay'
result.push(translation)
end
end
end
result.join(' ')
end
因此,这将给出以下内容:
puts translate('apple') # "appleay"
puts translate("quiet") # "ietquay"
puts translate("square") # "aresquay"
puts translate("the quick brown fox") # "ethay ickquay ownbray oxfay"
def translate(sentence)
sentence.split(" ").map do |word|
word = word.gsub("qu", " ")
word.gsub!(/^([^aeiou]*)(.*)/,'21ay')
word = word.gsub(" ", "qu")
end
end
这很有趣!我不喜欢 qu 的黑客,但我找不到一个好的方法来做到这一点。
所以对于这个猪拉丁语,我显然跳过了 and\an\in 和单数的东西,如 a\I 等。我知道这不是主要问题,但如果不是针对您的用例,您可以省略该逻辑。这也适用于三重辅音,如果你想保持它有一个或两个辅音,然后将表达式从 {1,3} 更改为 {1,2}
所有猪拉丁语都是相似的,所以只需根据您的用例进行更改即可。 这是使用MatchData
对象的好机会。 此外,vowel?(first_letter=word[0].downcase)
是一种风格选择,以便更识字,所以我不必记住单词[0]是第一个字母。
我的答案最初是基于塞尔吉奥·图伦采夫在这个线程中的回答。
def to_pig_latin(sentence)
sentence.gsub('.','').split(' ').collect do |word|
translate word
end.compact.join(' ')
end
def translate(word)
if word.length > 1
if word == 'and' || word == 'an' || word == 'in'
word
elsif capture = consonant_expression.match(word)
capture.post_match.to_s + capture.to_s + 'ay'
elsif vowel?(first_letter=word[0].downcase)
word + 'ay'
elsif vowel?(last_letter=word[-1].downcase)
move_last_letter(word) + 'ay'
end
else
word
end
end
# Move last letter to beginning of word
def move_last_letter(word)
word[-1] + word[0..-2]
end
private
def consonant_expression
# at the beginning of a String
# capture anything not a vowel (consonants)
# capture 1, 2 or 3 occurences
# ignore case and whitespace
/^ [^aeiou] {1,3}/ix
end
def vowel?(letter)
vowels.include?(letter)
end
def vowels
%w[a e i o u]
end
同样只是为了解决这个问题,我将包括我从撬动会话中的转储,以便你们都可以看到如何使用 MatchData。 敏斯旺。 正是这样的东西让红宝石变得很棒。
pry > def consonant_expression
pry * /^ [^aeiou] {1,3}/ix
pry * end
=> :consonant_expression
pry > consonant_expression.match('Stream')
=> #<MatchData "Str">
pry > capture = _
=> #<MatchData "Str">
pry > ls capture
MatchData#methods:
== begin end hash length offset pre_match regexp string to_s
[] captures eql? inspect names post_match pretty_print size to_a values_at
pry >
pry > capture.post_match
=> "eam"
pry > capture
=> #<MatchData "Str">
pry > capture.to_s
=> "Str"
pry > capture.post_match.to_s
=> "eam"
pry > capture.post_match.to_s + capture.to_s + 'ay'
=> "eamStray"
pry >
如果我正确理解了您的问题,您可以直接检查字符是元音还是辅音,然后使用数组范围来获取您想要的字符串部分。
vowels = ['a', 'e', 'i', 'o', 'u']
consonants = ('a'..'z').to_a - vowels
return str + "ay" if vowels.include?(str[0])
if consonants.include?(str[0])
return str[2..-1] + str[0..1] + "ay" if consonants.include?(str[1])
return str[1..-1] + str[0] + "ay"
end
str
这是一个处理"qu"音素以及其他不规则字符的解决方案。将单个单词放回具有适当间距的字符串时遇到了一点麻烦。任何反馈将不胜感激!
def translate(str)
vowels = ["a", "e", "i", "o", "u"]
new_word = ""
str.split.each do |word|
vowel_idx = 0
if vowels.include? word[0]
vowel_idx = 0
elsif word.include? "qu"
until word[vowel_idx-2]+word[vowel_idx-1] == "qu"
vowel_idx += 1
end
else
until vowels.include? word[vowel_idx]
vowel_idx += 1
end
end
idx_right = vowel_idx
while idx_right < word.length
new_word += word[idx_right]
idx_right += 1
end
idx_left = 0
while idx_left < vowel_idx
new_word += word[idx_left]
idx_left += 1
end
new_word += "ay "
end
new_word.chomp(" ")
end
我也做了一个
def translate(string)
vowels = %w{a e i o u}
phrase = string.split(" ")
phrase.map! do |word|
letters = word.split("")
find_vowel = letters.index do |letter|
vowels.include?(letter)
end
#turn "square" into "aresquay"
if letters[find_vowel] == "u"
find_vowel += 1
end
letters.rotate!(find_vowel)
letters.push("ay")
letters.join
end
return phrase.join(" ")
end
def piglatinize(word)
vowels = %w{a e i o u}
word.each_char do |chr|
index = word.index(chr)
if index != 0 && vowels.include?(chr.downcase)
consonants = word.slice!(0..index-1)
return word + consonants + "ay"
elsif index == 0 && vowels.include?(chr.downcase)
return word + "ay"
end
end
end
def to_pig_latin(sentence)
sentence.split(" ").collect { |word| piglatinize(word) }.join(" ")
end
这似乎可以处理我扔给它的所有内容,包括"qu"音素规则......
def translate str
letters = ('a'..'z').to_a
vowels = %w[a e i o u]
consonants = letters - vowels
str2 = str.gsub(/w+/) do|word|
if vowels.include?(word.downcase[0])
word+'ay'
elsif (word.include? 'qu')
idx = word.index(/[aeio]/)
word = word[idx, word.length-idx] + word[0,idx]+ 'ay'
else
idx = word.index(/[aeiou]/)
word = word[idx, word.length-idx] + word[0,idx]+'ay'
end
end
end
我用"qu"音素抓取单词,然后检查所有其他元音[不包括u]。
然后,我按第一个元音的索引(或"qu"情况下不带"u"的元音)拆分单词,并将该索引之前的单词部分放在单词的后面。并添加"ay"ftw。
这里的许多例子都相当长。这是我想出的一些相对较短的代码。它处理所有情况,包括"qu"问题!反馈总是很感激(我对编码很陌生)。
$vowels = "aeiou"
#First, I define a method that handle's a word starting with a consonant
def consonant(s)
n = 0
while n < s.length
if $vowels.include?(s[n]) && s[n-1..n] != "qu"
return "#{s[n..-1]}#{s[0..n-1]}ay"
else
n += 1
end
end
end
#Then, I write the main translate method that decides how to approach the word.
def translate(s)
s.split.map{ |s| $vowels.include?(s[0]) ? "#{s}ay" : consonant(s) }.join(" ")
end