2

pig-latin の文字列を翻訳するメソッドを ruby​​ で書こうとすると、ルールは次のようになります: ルール 1: 単語が母音で始まる場合、単語の最後に「ay」の音を追加します。

ルール 2: 単語が子音で始まる場合は、単語の末尾に移動し、単語の末尾に「ay」の音を追加し、単語が 2 つの子音で始まる場合は、両方を末尾に移動します。単語の「ay」を追加します

初心者として、私の問題は 2 番目のルールです。単語が 1 つの子音だけで始まる場合は機能しますが、複数の場合は機能させるのに苦労します。誰かコードを見て、どのようにコーディングできるか教えてもらえますかそれとは異なり、おそらく私の間違いは何か、おそらくコードのリファクタリングが必要です。ありがとう、これまでのところ、私はこのコードを思いつきました:

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") should == "アップルエイ"

translate("cherry") should == "エリーチャイ"

translate("three") should == "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 に答える
1

したがって、この豚のラテン語では、and\an\in および a\I などの単数形をスキップしたことは明らかです。それが主な質問ではないことはわかっていますが、ユース ケースでない場合は、そのロジックを省略できます。また、1 つまたは 2 つの子音を保持したい場合は、3 つの子音にも適用され、式を {1,3} から {1,2} に変更します。

すべての豚のラテン語は似ているので、ユースケースに合わせて変更してください。MatchDataこれはオブジェクトを使用する良い機会です。またvowel?(first_letter=word[0].downcase)、単語 [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

また、念のために、こじ開けセッションからのダンプを含めて、MatchData の使用方法をすべて確認できるようにします。ミンスワン。Ruby を素晴らしいものにしているのは、このようなものです。


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

これは、「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

私があなたの質問を正しく理解していれば、文字が母音か子音かを直接確認し、配列範囲を使用して必要な文字列の一部を取得できます。

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
  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 に答える