1

我有一个来自“简单”红宝石测验的例子。我想重新分配一个数组的值(例如 word1[0]),如果它等于(==)array1 的值到 array2 的值​​。看一下代码,很明显:

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
对于第二个单词,N 以 26
开头,并且根本不迭代对于第三个单词,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

现在,您将至少对每个单词保持字母扫描以相同的方式运行。但是,这也不会按预期工作,而是完全不同的原因。

您实际上如何使用N?

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

因此,您从 SEQUENCE 中读取 Nth WORD
.. 并将其与 array1 中的 Nth LETTER 进行比较。

这真的是你想做的吗?完全没有。

您很可能想要替换 WORD 中的每个字母以及由两个数组形成的字母对。

所以,相反,你想:

  • 从 WORD1 中读取第 N 个字母
  • 然后检查它在 array1 中的索引
  • 然后从该索引中读取替换字母
  • 然后将字母写回WORD中的第N位:

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

您也可以将其压缩为 oneliner:

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

但是,请注意我现在说position的不是N。您使用N的范围是 0..25,表示 ARRAY 中字母的索引。

但是,为了检查单词的字母,您需要遍历单词的 letters。这个词有多长?当然,不是 0..25!

还要注意细微的变化:word而不是word1. 我说“单词”和“单词的字母”,而不是“arrayofwords”。最初,您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来检查两个不同的数组,试试这个:

编辑 根据您的评论,由于您只需要如此争夺,因此这是一种可能的方法:

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 回答
0

我终于设法用一种非常简单的方法回答了我的问题:

def cypher(input_array)

  normal_array = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
  cypher_array = normal_array.rotate(2)
  awesome_cyphered_array = []

  input_array.each do |element|
    0.upto(25) do |i|
      case element
        when normal_array[i]
          awesome_cyphered_array << cypher_array[i]
      end
    end
  end
  puts awesome_cyphered_array.join  
end

# START of my program
puts "Enter a sentence, it will be cyphered!"
sentence = gets.chomp
length = sentence.length
sentence_as_array = sentence.upcase.split(//).reverse!

make_it_an_array = []

1.upto(length) do 
  make_it_an_array << sentence_as_array.pop
end

cypher(make_it_an_array)
于 2013-05-08T14:55:29.213 回答