2013-06-28 38 views
0

我正在嘗試編寫一個SML函數,它將返回給定數字的所有素數因子列表。這將最終成爲稍後其他功能的輔助函數。SML - 素因子分解,構建列表錯誤

本來bigNumber是我需要找到主要因素的數量,而我通過的數量比作爲除數的數字少1。這裏有一個例子,我怎樣稱它來找到數字100的主要因素。getPrimeFactors 100 99;

我並不太擔心現在算法是否存在缺陷,但如果您發現它的任何錯誤我很樂意傾聽。

我的主要問題是嘗試將遞歸鏈的返回值作爲列表傳遞,然後將這些列表與其他列表進行組合。

fun getPrimeFactors bigNumber divisor = 
    if divisor > 0 then 
     if (bigNumber mod divisor) = 0 then List.concat(getPrimeFactors (bigNumber div divisor) ((bigNumber div divisor) - 1), getPrimeFactors divisor (divisor - 1)) 
     else [getPrimeFactors bigNumber (divisor - 1)] 
    else [bigNumber]; 

運行這會給我這個錯誤。 C:..... \ run.x86-win32.exe:致命錯誤 - 未捕獲的異常錯誤0 在../compiler/TopLevel/interact/evalloop.sml:66.19-66.27

C:\.....\commonFactors.sml:3.39-3.160 Error: operator and operand don't agree [tycon mismatch] 
    operator domain: 'Z list list 
    operand:   'Y * 'Y 
     in expression: 
      List.concat 
      ((getPrimeFactors (<exp> div <exp>)) (<exp> div <exp> - 1), 
      (getPrimeFactors divisor) (divisor - 1)) 
[Finished in 0.4s with exit code 1] 
募集

任何幫助將不勝感激!

回答

2

您試圖在元組上調用List.concat。該類型List.concat是

fn : 'a list list -> 'a list 

也就是說,它需要一個列表的列表,這些串接的所有在一起,並返回結果。這是你的錯誤。

如果,而是採用List.concat,我們使用@操作,我們得到一個不同的錯誤(這可能會略有不同的系統上):

File "test.sml", line 7, characters 14-53: 
!   else [getPrimeFactors bigNumber (divisor - 1)] 
!    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
! Type clash: expression of type 
! 'a list 
! cannot have type 
! 'a 
! because of circularity 

這個錯誤是因爲getPrimeFactors應該返回int list,但在這裏您試圖將結果從getPrimeFactors填充到列表中,因此得到int list list

+0

謝謝!從()更改List.concat到[]並且很好。我對SML很陌生,很難找到好的資源,似乎比其他語言少得多。 –

+1

我可以推薦[這本書](http://www.amazon.com/Introduction-Programming-International-Computer-Science/dp/0201398206)。 – Tayacan

0

只是爲了防止任何人感到好奇,這裏是正確的算法修正後的代碼。感謝Tayacan能夠修復List.concat錯誤。

fun getPrimeFactors big small = 
    if small > 1 then 
     if (big mod small) = 0 then List.concat[(getPrimeFactors (big div small) (big div small - 1)), (getPrimeFactors small (small - 1))] 
     else List.concat[(getPrimeFactors big (small - 1))] 
    else if big = 1 then nil 
     else [big]; 
+0

是的,你實際上並不需要使用List.concat。您只是將兩個列表連接在一起,所以只需使用'@'運算符;) 另外,您當前的問題:運行'getPrimeFactor 2 1'時會發生什麼? – Tayacan

+0

使用@會更高效嗎? –

+0

併爲getPrimeFactors 2 1我得到2這是正確的根據這[鏈接](http://www.sosmath.com/tables/factor/factor.html) –