0

我正在尝试编写一个 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: 致命错误 -- 未捕获的异常 ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27 引发的错误为 0

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]

任何帮助将不胜感激!

4

2 回答 2

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.

于 2013-06-28T13:18:40.463 回答
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];
于 2013-06-28T14:02:33.493 回答