2016-10-15 30 views
2

運行下面的代碼時,我得到了一個令人驚訝的輸出結果。爲什麼word變量的值在第三次調用遞歸函數時進入while循環之前和之後會發生變化?爲什麼這個詞在while循環內部和外部是不同的?

def get_perms(word) 
    perms = [] 
    get_perm_recursive("",word, perms) 
    perms 
end 

def get_perm_recursive(prefix, word, perms) 
    puts "---------------------" 
    if word.length == 0 
    perms << prefix 
    end 

    i = 0 
    puts "Word outside loop: #{word}" 
    while i < word.length 
    puts "Word inside loop: #{word}" 
    prefix << word[i] 
    new_word = word[0...i] + word[i+1..-1] 
    get_perm_recursive(prefix, new_word, perms) 
    i += 1 
    end 

end 

get_perms("ab") 

輸出:

--------------------- 
Word outside loop: ab 
Word inside loop: ab 
--------------------- 
Word outside loop: b 
Word inside loop: b 
--------------------- 
Word outside loop: 
Word inside loop: ab 
--------------------- 
Word outside loop: a 
Word inside loop: a 
--------------------- 
Word outside loop: 
+0

歡迎來到SO!我不確定你真的想在這裏做什麼。循環不是範圍門,並且每次調用#get_perm_recursive時都要改變* word *的大小(因此也就是循環條件)。表達真實目標可能有更好的方法。用你的預期結果更新你的問題(不僅僅是問題代碼)將是一個很大的幫助。 –

回答

0

你必須在它的循環遞歸函數。嘗試添加一些額外的日誌記錄:

def get_perms(word) 
    perms = [] 
    $level = 0 
    get_perm_recursive("",word, perms) 
    perms 
end 

def get_perm_recursive(prefix, word, perms) 
    $level += 1 
    puts "level: #{$level}" 
    puts "entering get_perm_recursive(#{prefix},#{word},#{perms}" 
    if word.length == 0 
    perms << prefix 
    end 

    i = 0 
    puts "Word outside loop: #{word}" 
    while i < word.length 
    puts "Word inside loop: #{word}, #{i}" 
    prefix << word[i] 
    new_word = word[0...i] + word[i+1..-1] 
    puts "Calling gets_perm_recursive recursively" 
    get_perm_recursive(prefix, new_word, perms) 
    i += 1 
    end 
    puts "done with gets perm recursive #{$level}" 

    $level -= 1 
end 

get_perms("ab") 

輸出:

level: 1 
entering get_perm_recursive(,ab,[] 
Word outside loop: ab 
Word inside loop: ab, 0 
Calling gets_perm_recursive recursively 
level: 2 
entering get_perm_recursive(a,b,[] 
Word outside loop: b 
Word inside loop: b, 0 
Calling gets_perm_recursive recursively 
level: 3 
entering get_perm_recursive(ab,,[] 
Word outside loop: 
done with gets perm recursive 3 
done with gets perm recursive 2 
Word inside loop: ab, 1 
Calling gets_perm_recursive recursively 
level: 2 
entering get_perm_recursive(abb,a,["abb"] 
Word outside loop: a 
Word inside loop: a, 0 
Calling gets_perm_recursive recursively 
level: 3 
entering get_perm_recursive(abba,,["abba"] 
Word outside loop: 
done with gets perm recursive 3 
done with gets perm recursive 2 
done with gets perm recursive 1 
1

它不是。你誤解了正在產生輸出的迭代。

--------------------- # this is iteration 1 
Word outside loop: ab # this is iteration 1 
Word inside loop: ab # this is iteration 1 
--------------------- # this is iteration 2 
Word outside loop: b # this is iteration 2 
Word inside loop: b # this is iteration 2 
--------------------- # this is iteration 3 
Word outside loop: # this is iteration 3 
# Iteration 3 has NO FURTHER OUTPUT (because i is not less than word.length) 
# we are returned to Iteration 2 
# but... Iteration 2 ALSO has NO FURTHER OUTPUT (because i in that iteration, increased to 1, is not less than word length) 
# we are returned to Iteration 1 
Word inside loop: ab # this is the SECOND while loop in the first iteration, so yes, the word is "ab" 

下面是修改輸出看你在什麼迭代一個簡單的方法...第一次迭代中有一個iteration參數默認爲1,並遞增每個調用到下一次迭代:

def get_perm_recursive(prefix, word, perms, iteration=1) 
    puts "---------------------" 
    if word.length == 0 
    perms << prefix 
    end 

    i = 0 
    puts "Word outside loop: #{word} in iteration: #{iteration}" 
    while i < word.length 
    puts "Word inside loop: #{word} in iteration: #{iteration}"" 
    prefix << word[i] 
    new_word = word[0...i] + word[i+1..-1] 
    get_perm_recursive(prefix, new_word, perms, iteration + 1) 
    i += 1 
    end 

end 

順便說一句......你似乎期待get_perms返回一個燙髮數組(排列?)。但是你沒有機制返回排列調用中計算的perms。您需要確保每種方法都返回perms,並且您需要將返回的perms分配給一個變量。

更改第一種方法......

def get_perms(word) 
    perms = [] 
    perms = get_perm_recursive("",word, perms) 
    perms 
end 

......從而使get_perm_recursive的結果分配給一個變量,甚至更好,只是有get_perm_recursive作爲最後執行的語句。

def get_perms(word) 
    get_perm_recursive("",word, []) 
end 

您還需要捕獲的get_perm_recursive的輸出中get_perm_recursive,所以更換,

get_perm_recursive(prefix, new_word, perms) 

perms = perms + get_perm_recursive(prefix, new_word, perms) 

而且get_perm_recursive方法的最後聲明應該返回perms陣列...

i += 1 
    end 
    perms 

end 

另一件事我會提,結構

i = 0 
while i < limiting_value 
    ... 
    i += 1 
end 

...是不是紅寶石式的。更典型和更好的實施方式是

(0...limiting_value) do |i| 
    ... 
end 
+0

謝謝!很有幫助 :) –

相關問題