猪拉丁语方法翻译



尝试用 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

最新更新