1

この例は、「簡単な」ルビクイズからのものです。array1 の値と array2 の値が等しい (==) 場合、配列の値 (word1[0] など) を再割り当てしたいと考えています。明らかなように、コードを見てください。

array1 = Array.new
array1 = ('A'..'Z').to_a

array2 = Array.new
array2 = ('A'..'Z').to_a
array2 = array2.rotate(2)

puts "enter a word:"
word1 = gets.chomp
word1 = word1.upcase.split(//)

n = 0

word1.each do
  while n < 26
    if word1[n] == array1[n]
      word1[n] = array2[n]
    end
    n += 1
  end
end

puts word1   # This word should now be "encoded" and not easy to read.

このコードを試してみましたが、入力した単語の 1 ~ 2 文字だけがランダムに変更されます (gets.chomp)。

したがって、word1は私が期待している配列であり、各要素(文字)がarray1 [0]と比較され、等しい場合はarray2 [0]の値に再割り当てされます。word1[0] と array1[0] が等しくない場合、'n' の値が +1 に変更され、ブロックが再度実行されます。

注: この問題を簡単に説明したくはありません。ここで何が起こっているのか、そして各反復が期待どおりに機能しない理由を本当に理解したいのです。もしあなたがこの質問に「私の知識レベル」で答えることができれば、それは本当に素晴らしいことです!

4

3 に答える 3

1

まず、連続する単語の間にカウンター N をリセットするのを忘れました。N をゼロに設定してから、単語の反復処理を開始します。

したがって、概要では、アルゴリズムは次のように動作します。

最初の単語では、N は 0..25 を繰り返します。2
番目の単語では、N は 26 で始まり、まったく繰り返されません
。3 番目の単語では、N は 26 で始まり、繰り返されません

したがって、完全な初心者のために、次のようにします。

array1 = Array.new
array1 = ('A'..'Z').to_a

array2 = Array.new
array2 = ('A'..'Z').to_a
array2 = array2.rotate(2)

puts "enter a word:"
word1 = gets.chomp
word1 = word1.upcase.split(//)     # <-- note that you REPLACE the input string
                                   # with an sequence of STRINGS produced by SPLIT

word1.each do                      # for each STRING in the SEQUENCE
  n = 0
  while n < 26                     # scan all 26 letters from ARRAY
    if word1[n] == array1[n]       # ... WTF
      word1[n] = array2[n]
    end
    n += 1
  end
end

ここで、文字のスキャンを少なくとも 1 単語ごとに同じ方法で実行し続けます。ただし、これも期待どおりには機能しませんが、まったく別の理由です。

Nを実際にどのように使用しますか?

    if word1[n] == array1[n]
      word1[n] = array2[n]
    end

したがって、SEQUENCE から N 番目の WORD を読み取り、
それを array1 の N 番目の LETTER と比較します。

それは本当にあなたがやりたかったことですか?そうではありません。

おそらく、WORD のすべての文字を、2 つの配列によって形成された文字のペアに置き換えたいと思うでしょう。

そのため、代わりに次のことを行います。

  • WORD1 から N 番目の文字を読み取る
  • 次に、array1 のどのインデックスにあるかを確認します
  • 次に、そのインデックスから置換文字を読み取ります
  • 次に、WORD の N 番目の位置に手紙を書き戻します。

    letter = word[position]
    letterindex = array1.index(letter)
    substitution = array2[letterindex]
    word[position] = subsitution
    

それをワンライナーに圧縮することもできます:

 -- loop
    -- loop2
      word[position] = array2[array1.index(word[position])]

positionただし、ではなく、今言っていることに注意してくださいNNARRAY の文字のインデックスを意味する範囲 0..25 として使用しました。

ただし、単語の文字を検査するには、単語の文字を反復処理する必要があります。単語はどれくらいですか?確かに、0..25 ではありません!

微妙な変更にも注意してください:wordの代わりにword1. 「単語の配列」ではなく、「単語」と「単語の文字」と言います。もともと、Nシーケンスから N 番目の単語を読み取るためにも使用していましたが、そのままにしておきましょう。しかし、単語の文字を繰り返し処理する必要があるため、別の変数が必要ですposition

n = 0

arrayOfWords.each do

    word = arrayOfWords[n]

    position = 0

    while position < word.length
        letter = word[position]
        letterindex = array1.index(letter)
        substitution = array2[letterindex]
        word[position] = subsitution
        position += 1
    end

    n += 1
end

現在の単語の実際の長さを反復するために、Nが各単語にとどまり、増加するだけであり、が毎回ゼロにリセットされることに注意してください。position

Ruby では、これは非常に手の込んだ方法です。Ruby には、コードを短縮できるすばらしいトリックがたくさんあります。たとえば、eachメソッドはループだけではありません。それは実際に各単語* を提供します。N はまったく必要ありません。

arrayOfWords.each do |word|

    position = 0

    while position < word.length
       word[position] = array2[array1.index(word[position])]
       position += 1
    end

end

バーに「単語」を追加した方法に注意してください || each呼び出しに。同様の方法で も実際に取り除くことができますpositionが、その場合はコードが短くなりますが、読みにくく、理解しにくくなります。

于 2013-02-21T13:13:51.923 に答える
0

n問題は、同じ「カウンター」を使用して2つの異なる配列をチェックしていることだと思います。これを試してください:

編集 あなたのコメントによると、スクランブルが必要なだけなので、可能な方法は次のとおりです。

array1 = ('A'..'Z').to_a
array2 = ('A'..'Z').to_a.shuffle

puts "enter a word:"
word1 = gets.chomp
word1 = word1.upcase.split(//)

n = 0

word1.each do
  word1[n] = array2[n]
  n +=1
end

puts word1

同じ単語を使用しても、常に異なる入力が生成さshuffleれます。array2

于 2013-02-21T12:30:33.327 に答える