2

尝试用 ruby​​ 编写 Method 来翻译 pig-latin 中的字符串,规则: 规则 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”

translate("three") 应该 == "eethray"

4

11 回答 11

4

不需要所有那些花哨的正则表达式。把事情简单化。

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"
于 2012-11-21T17:42:48.290 回答
3

这将处理多个单词、标点符号和诸如 '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
于 2013-07-01T17:06:27.827 回答
2

好吧,这是一个史诗般的猪拉丁语翻译器,我确信可以使用一些重构,但通过了测试

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"
于 2014-05-14T18:36:37.067 回答
2
def translate(sentence)
  sentence.split(" ").map do |word|
    word = word.gsub("qu", " ")
    word.gsub!(/^([^aeiou]*)(.*)/,'\2\1ay')
    word = word.gsub(" ", "qu")
  end
end

那很有趣!我不喜欢 qu 的 hack,但我找不到这样做的好方法。

于 2015-01-02T23:24:05.383 回答
1

因此,对于这个猪拉丁语,我显然跳过了和 \an\in 以及像 a\I 等奇异的东西。我知道这不是主要问题,但如果它不适合您的用例,您可以忽略该逻辑。如果你想用一个或两个辅音保留它,这也适用于三重辅音,然后将表达式从 {1,3} 更改为 {1,2}

所有猪拉丁语都是相似的,因此只需根据您的用例进行更改。MatchData这是使用对象的好机会。也是vowel?(first_letter=word[0].downcase)一种风格选择,以提高识字率,因此我不必记住 word[0] 是第一个字母。

我的回答最初是基于 Sergio Tulentsev 在这个帖子中的回答。


  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

也只是为了它,我将包括我从一个 pry 会话中的转储,这样你们都可以看到如何使用 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 >
于 2016-03-19T23:00:04.850 回答
0

如果我正确理解了您的问题,您可以直接检查一个字符是元音还是辅音,然后使用数组范围来获取您想要的字符串部分。

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
于 2012-11-21T17:41:33.163 回答
0

这是一个处理“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
于 2015-05-24T20:16:08.250 回答
0

我也做了一个

    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
于 2016-02-12T01:58:43.757 回答
0
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
于 2016-07-09T23:33:30.247 回答
0

这似乎处理了我扔给它的所有内容,包括“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。

于 2016-08-10T12:55:29.260 回答
0

这里的许多示例都相当长。这是我想出的一些相对较短的代码。它处理所有情况,包括“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
于 2017-05-16T18:56:35.930 回答