【发布时间】:2020-04-18 00:41:52
【问题描述】:
我正在尝试在 Haskell 中为我的自定义列表数据类型实现自定义乘法运算,它使用 Int 和 [Int]。Int 用于通过模除法来减少整数,我将其称为d.[Int]代表列表的内容
假设a 和b 是两个具有相同d 的列表。a的长度是w,b的长度是v
c = a*b 是:
c[k] = a[0] * b[k] + a[1] * b[k - 1] + a[2] * b[k - 2] + · · · + a[k] * b[0]
最后,c[k] 减少了 mod d。c = w + v - 1的长度
意思是c[k]中的索引k可以大于w和v的长度。
为了解决这个问题,我为原始列表边界之外的索引连接了一个 0 元素列表。
澄清一下:
c[0] = (a[0] * b[0]) % d
c[1] = (a[0] * b[1] + a[1] * b[0]) % d
c[2] = (a[0] * b[2] + a[1] * b[1] + a[2] * b[0]) % d
.
.
.
c[w + v - 1]
例如,a = [3,2,4] 和 b = [7,9,7,2],两者都有 d = 31。
在代码中,当它们相乘时,它们是 [3,2,4,0,0,0] 和 [7,9,7,2,0,0]
在此示例中,c = a * b = [21, 10, 5, 25, 1, 8]
这是我的代码:
module Custom where
data CustomList = CustomList Int [Int]
instance Num CustomList where
(CustomList a1 b1) * (CustomList a2 b2) =
if length b1 >= 1 && length b2 >= 1 then do
let llen = (length b1) + (length b2) - 1
--concatenating a list of 0 elements for indices outside the bounds of the original list.
let sub_b1 = llen - (length b1)
let sub_b2 = llen - (length b2)
let zeros_b1 = map (0*) [1..sub_b1]
let zeros_b2 = map (0*) [1..sub_b2]
--matching list lengths
let new_b1 = b1++zeros_b1
let new_b2 = b2++zeros_b2
--trying to mimic a nested for loop
let ans = [ (new_b1 !! x) * (new_b2 !! y) | x <- [0..llen-1], y <- (reverse [0..x]) ]
CustomList (a1) (map (`mod` (a1)) ans)
else do
0
instance Show CustomList where
show (CustomList a b) = "output: " ++ (show b) ++ "\nlength: " ++ (show a)
输出:
*Custom> let a = CustomList 31 [3,2,4]
*Custom> let b = CustomList 31 [7,9,7,2]
不正确(我得到的)
*Custom> a * b
output: [21,18,14,28,5,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
length: 31
正确(我应该得到什么)
output: [21, 10, 5, 25, 1, 8]
length: 6
我意识到我的逻辑有问题:
-
x计数器,对于所有c[k]计算,我需要从a[0]开始并以a[k]结束,但我从a[x]开始。 - 未将答案汇总在一起。例如,我没有获得
c[1] = a[0] * b[1] + a[1] * b[0],而是获得c[1] = a[0] * b[1]&c[2] = a[1] * b[0]
我不知道如何解决它,我一直在尝试,但最终只是通过尝试来制造新问题。
我是 Haskell 的新手,所以我更喜欢用简单易读的方法来解决这个问题,而不是更“Haskell”的方法。 但任何帮助表示赞赏,在此先感谢。
【问题讨论】:
标签: haskell functional-programming