2013-02-21 35 views
1

我有一个“简单”的红宝石测验这个例子。如果它等于(==)array1的值和array2的值,我想重新分配一个数组的值(例如word1 [0])。看看代码,以便它是显而易见的:红宝石测验 - 重新分配数组值与while循环

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,并且块再次运行。

注意:我不想为这个问题有一个简单的公式,我想真正理解这里发生了什么,以及为什么我的每一次迭代不像我期望的那样工作。所以如果你能以“我的知识水平”来回答这个问题,那真是太棒了!

回答

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) 
+0

请不要把这个评论看作是冒犯性的,但是:(1)更短并不意味着更简单,(2)它仍然比应该复杂得多(你使用upto/case/(3)这段代码实际上不会**回答你的问题 - 它回答了你产生问题的问题,但是,当你使用非常奇怪的方式时,string-> array是一个没有循环的单行代码。不是问题,(4)我并不需要从“接受”的答案中得到15rep,但我认为在几个月之后重新分配点数是不恰当的 - 对于之前的答案,您似乎很满意,那么为什么要回溯到时间? ;) – quetzalcoatl 2013-05-08 17:10:59

+0

不要删除你的答案/代码,只需擦亮它!删除那个奇怪的字符串到数组的转换(String类有'each_char'方法),并改变upto(25)-case-当进行一些合理的查找时,可以使用一个简单的散列或'index'方法。真的,没有必要到处循环;) – quetzalcoatl 2013-05-08 17:12:44

+0

你是对的,我的答案仍然可以重构。但作为一个红宝石初学者,我更容易理解,这就是为什么我想发布它。我会在接下来的几天内重构它。感谢您的积极反馈!谢谢你的帮助 – rubybrah 2013-05-08 23:37:11

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 

它总是会产生不同的输入,即使你在array2

使用相同的字,因为 shuffle
+0

我运行你的代码,它有相同的结果作为我的。尝试运行你的代码,你会问我的问题。 – rubybrah 2013-02-21 12:44:34

+0

请给我一个预期的输出;) – Gerep 2013-02-21 12:48:14

+0

输入:HELLO;输出:JGNNQ,因为H = J,E = G L = N,L = N,O = Q; – rubybrah 2013-02-21 12:53:00

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 

所以,你从序列
读第N WORD ..并将其与从阵列1第N个字母。

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

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

所以,相反,你想:

  • 从WORD1
  • 读出的第N个字母
  • 那么它是什么指数在阵列1
  • 检查,然后读取的替代信索引
  • 然后将该字母写回第N位WORD:

    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中字母的索引。

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

还要注意细微的变化:word而不是word1。我说“单词”和“单词的字母”,而不是“单词”。最初,您还使用N来读取序列中的第N个字,让我们保留它。但是,当我们需要遍历字的leters,需要一个不同的变量,“说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,但这反过来会缩短代码,但很难阅读/理解。

+0

您应该教授课程! :)非常感谢你 – rubybrah 2013-02-21 13:18:23

+0

不,不,不,这是太多错误:(对不起,我误了你的原始线路之一。请稍候,我会更新帖子 – quetzalcoatl 2013-02-21 13:20:17

+0

至少你已经让我明白重置我的计数器在迭代之间! – rubybrah 2013-02-21 13:23:47