2013-02-21 37 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