2009-12-04 81 views
0

我是一個新手,紅寶石,並與獲得的代碼有問題下面的工作Ruby:調用函數時出現TypeError錯誤。發生了什麼?

def factorial(n) 
    if n == 0 
    1 
    else 
    n * factorial(n-1) 
    end 
end 

puts factorial(numbers) 

我不斷收到錯誤消息不能轉換爲長整數數組(類型錯誤)在'因子」。任何人能夠幫助我回答我在這種情況下做錯了什麼?在此先感謝

+1

如何被定義的數字?你有沒有試過'put factorial(200)'或類似的東西?您是否驗證過這些數字是數字而不是數組? – Earlz

回答

3

我不知道任何紅寶石,但我懷疑numbers是一個數組的數組,而不僅僅是一個,當你通過它factorial它試圖執行計算和爆炸。 (將一個數組與零相比,將其乘以或減去是沒有意義的。)

您需要更改factorial以接受多個數字並找到每個數的階乘,或(更容易)更改調用代碼在一組數字上一次計算一個因子。

+0

我剛剛破解了irb來測試這個。如果數字是一個數組,它確實會給出這個錯誤。但它抱怨 - 方法。 Ruby不關心哪些類型與==進行比較,一個數組永遠不會等於0,所以它繼續前進,並試圖從數組中減去1並在那裏爆炸。 你想要調用你的數組,可能是這樣的: numbers.each do | number | 輸入因子編號 結束 如果您真的想要,您可以編寫一個小包裝方法。或者如果你想要一個陣列退出,你可以做... 把數字。收集{| number |因子數} –

+0

是的,我意識到錯誤的基礎上,我最初的想法(比較時它被炸燬了)可能是不正確的,它可能在後面的乘法或減法期間,所以我編輯了我的答案來對衝我的賭注; ) – mquander

+0

那麼,[1,2,3] * 3在Ruby中返回[1,2,3,1,2,3,1,2,3],但是你的觀點是站立的。 –

6

正如mquander所說,numbers顯然是一個數組。

所以,你需要的是這樣的:

puts(numbers.map { |n| factorial(n) }) 

而且,順便說一句,你的錯誤無關遞歸。

確認mquander的理論:

> numbers = [1,2,3] 
> puts factorial(numbers) 
TypeError: can't convert Fixnum into Array 

而只是出於好奇,這裏是你如何在Ruby中實現階乘沒有遞歸,這樣你就不會得到堆棧溢出的大量涌現。

def factorial(n) 
    (1..n).inject(1) { |ac, x| ac * x } 
end 
0

你可能尋找喜歡的東西:

numbers.map { |n| factorial(n) } 
0

作爲除了KCH的代碼,你可以修改函數來處理這兩個數組和標量輸入。

def factorial(n) 
    if n.is_a?(Array) 
    return n.map {|n| factorial(n)} 
    end 
    raise unless n.is_a?(Integer) and (n >= 0) 
    (n == 0) ? 1 : n * factorial(n-1) 
end 

此功能處理

編輯標量,數組,嵌套數組,無效的東西,等:成立KCH的簡化類型檢查代碼

+1

不是試圖處理各種意外的輸入,而是最好確定你正在得到一個數字,實際上是一個正整數,它是階乘函數的正確域。所以,除非n.is_a?(Integer)和n> = 0,否則'raise raise – kch

+0

由於提交者正在向他的函數中提供一個數組,因此我認爲需要處理這種輸入的函數。如果不需要數組支持,那麼是的,你的解決方案是一個更清潔的(我總是忘記'raise')。 – bta

+0

現在我重新思考它,不應該需要類型檢查。像這樣的函數可以作爲一個成員函數來實現,像Integer這樣的類會被擴展來包含它(所以你可以用類似'x = 212.factorial'的方式來調用它),所以這個參數是隱含的,保證類型。 – bta

相關問題