我正在尝试创建一个函数,该函数将查找给定列表的3个相同且相邻的数字,对于我正在尝试实现的求解器。然后,如果有3个相同且相邻的数字,则将第1个和第3个相同的数字标记为“0”,并将中间值设置为负数。
我想知道为什么这会给我一个错误。:
change xs = chnge xs []
where
chnge xs acc
| length xs <= 2 = [acc]
| (head xs == xs !! 1) && (head xs == xs !! 2) = [0, (xs !! 1)*(-1), 0] ++ tail xs
| otherwise = chnge (tail xs) (acc ++ head xs)
答案 0 :(得分:8)
由于acc
是一个列表,我们不希望在[acc]
的第一个后卫中返回chnge
,而只是acc
;同样在otherwise
行,您不希望acc ++ head xs
这意味着xs
是一个列表列表 - 其第一个成员可以如何附加?相反acc ++ [head xs]
所以可能:
change xs = chnge xs [] where
chnge xs acc
| length xs <= 2 = acc
| (head xs == xs !! 1) && (head xs == xs !! 2) = [0, (xs !! 1)*(-1), 0] ++ tail xs
| otherwise = chnge (tail xs) (acc ++ [head xs])
这看起来有些偏差,但真正的问题是“模式匹配”的缺乏以及head
,tail
和!!
的危险使用。尝试更像这样的东西,也许吧? (虽然它不使用累加器):
change [] = []
change [x] = [x]
change [x,y] = [x,y]
change (x:y:z:ws) | x == y && y == z = 0 : (-y) : 0 : change ws
change (x:xs) = x : change xs
-- *Main> change [12,12,66,66,66,44,44,99,99,99,76,1]
-- [12,12,0,-66,0,44,44,0,-99,0,76,1]
连续三个案例可以被视为一种模式,因此我们在它们相等的时候提出一个特例。