乘以"大蚂蚁"在哈斯克尔

时间:2018-02-08 06:10:38

标签: haskell

我应该在haskell中为大数字实现乘法运算。 大数字表示为列表,例如123是[1,2,3]。 到目前为止,我已经实施了添加,

bigPlus [1,2,3] [4,5,6] 
> [5, 7, 9]

但是现在,我必须做bigMultiply,但我已经陷入困境,因为我必须根据作业给出的骨架代码来实现它,我不允许更改骨架代码(但我允许添加嵌套"其中")

bigMul :: [Int] -> [Int] -> [Int]
bigMul l1 l2 = res
  where
    (_, res)   = foldRight f base args
    f x (z, p) = error "TBD"
    base       = error "TBD"
    args       = error "TBD"

其中

foldRight::(b -> a -> a) -> a -> [b] -> a
foldRight = foldr

我还编写了一个名为digitMul的方法

digitMul :: Int -> [Int] -> [Int]

digitMul 5 [1,1]
> [5,5] 

digitMul 0 [1,2,3]
> []

和digitMul是用bigPlus编写的。有人可以帮助我理解和弄清楚我有什么吗?我完全迷失了这个。

其他可能有用的方法是

replicate :: a -> Int -> [a]
-- | `replicate x n` returns a `[x,x,...,x]` containing `n` copies of `x`
--
-- >>> replicate 3 5
-- [3,3,3,3,3]

Zeros :: [Int] -> [Int] -> ([Int], [Int])
-- | `Zeros l1 l2` returns a pair (l1', l2') which are just the input lists,
--   padded with extra `0` on the left such that the lengths of `l1'` and `l2'`
--   are equal.
--
-- >>> Zeros [9,9] [1,0,0,2]
-- [0,0,9,9] [1,0,0,2]
--
-- >>> Zeros [1,0,0,2] [9,9]
-- [1,0,0,2] [0,0,9,9]

remZero :: [Int] -> [Int]
-- | `remZero ds` strips out all leading `0` from the left-side of `ds`.
--
-- >>> remZero [0,0,0,1,0,0,2]
-- [1,0,0,2]
--

1 个答案:

答案 0 :(得分:6)

对于实际使用,Integer已经是Haskell中的big-int类型,并且说实话,您可以简单地转换为Integer,乘以并转换回来。

这听起来像是家庭作业,所以我不会给出完整的答案,但这里有一些提示。

由于你无法更改样板,你需要将其写为foldr操作,它将从后到前运行(即在那些,然后是数十,然后是数百),产生一对并将其传递给折叠的下一次迭代。您可以自由定义该对的第一个元素,但第二个元素必须是结果,也就是说,BigInt列表。因此,您将在每次迭代时计算算法的一个步骤,并在该对的第二个组件中传递它。您可以使用的一种方法是迭代其中一个被乘数的数字,将另一个数乘以该数字,再乘以您所在的位置(1,然后是10,然后是100),并添加到累加器。这复制了我被教导如何手工繁殖(也许你用网格学习,这也可能与Haskell有关)。

如果你这样做,你传递给下一次迭代的另一个元素必须是基础,它需要在res对的第一个组件中传递,因为这是唯一的另一种方式让你传递它。 base元素应该是传递给foldr的初始值,包含那些位置和零累加器。此函数为f,其中x是被乘数的当前数字,z是要添加的零的数量和到目前为止的p运行总和。

这应该足以让你编写程序。