我正在尝试使用Haskell中的分而治之方法编写Karatsuba算法。我使用合并排序算法完成了此操作,但此处无法解决,这有点尴尬。
我的主要功能如下:
dz test end divide combine x =
if test x then end x
else combine(map(dz test end divide combine) (divide x))
我测试了它的值1234
和5678
:dz test end divide combine [1234, 5678,2]
。
所以我必须编写test
,end
,divide
和combine
函数。
lengthNumb x = length . show $ x
test (x:x1:xs) = (lengthNumb x) < 4 || (lengthNumb x1) < 4
end (x:y:z:xs) = [x * y, z]
这非常简单。我只是检查两个要乘的数字是否至少都长4位数字。如果不是,我只使用简单的乘法并携带m
值。我知道Karatsuba对于更大的数字效果更好,但这只是出于测试目的。
divide [] = []
divide (x:x1:x2:xs) =
let y1 = x `div` 10^x2
y2 = x `mod` 10^x2
y3 = x2 `div` 2
z1 = x1 `div` 10^x2
z2 = x1 `mod` 10^x2
in [[y1,y2,y3],[z1,z2,y3],[y1+y2, z1+z2, y3]]
combine [[x, x1],[y,y1],[z,z1]] = x * 10^(2*x1) + y + (z - x - y) * 10^x1
有人告诉我combine
函数应该只做最后的乘法。因此,我想它应该获得三个数字作为输入(每个数字都带有其m
值),然后还要进行必要的减法运算(z-x-y
,因为我无法在divide
中进行运算。
但这是错误的。我收到一个错误:
Occurs check: cannot construct the infinite type: a ~ [a]
Expected type: [[a]] -> [a]
Actual type: [[[a]]] -> [a]
我认为combine
函数的参数有问题,但我不知道如何解决。我还认为combine
和divide
的工作方式可能存在问题,因为在先前的迭代之一中,乘法的最终结果是错误的。