2

我有一个接收列表的函数,如果列表中有 2 个相同且连续的数字,并且如果列表中的其他地方有一个数字 x,那么我想将 x 更改为 0 和返回列表。

twoAdjThenThirdZero (x:y:xs) = [if x == y && x `elem` xs then 0 else x | x <- xs]

出于某种原因,每次我尝试运行它时都会忽略列表中的前两个元素。

*Main> twoAdjThenThirdZero [2,3,4,1,2,0,2,3,3]

[4,1,2,0,2,0,0]

此外,上述情况与我想要的相反。我想将两个 3 保留在列表的末尾,并使第二个元素,即 3,为 0。但它被调换了。

*Main> twoAdjThenThirdZero [2,2,3,1,2,4]

[3,1,0,4]

有人知道为什么是这样吗?提前致谢!

4

2 回答 2

2

试试这个:

adjToZero = adjToZero' (allDoubles xs) 

adjToZero' ds [] = []
adjToZero' ds [x] = [x]
adjToZero' ds (x:y:xs) = if (x/=y) && (x `elem` ds) then 0:(adjToZero' ds (y:xs))
                                                    else x:(adjToZero' ds (y:xs))

allDoubles [] = []
allDoubles (x:y:xs) = if (x==y) then x:(allDoubles xs)
                                else allDoubles (y:xs)

例子:

> adjToZero [1,2,1,1]
[0,2,1,1]
于 2012-10-07T20:27:51.340 回答
1

我在这里看到了多个问题。首先解构函数声明中的参数列表twoAdjThenThirdZero (x:y:xs)。如果你想继续得到每一步的x和y,你必须递归。相反,您切换到使用列表推导和 x 的副本。在列表推导中,您将通过 xs,它是函数参数的所有元素,除了前两个(x 和 y)。

如果您大声阅读列表理解,我认为您可以弄清楚。

“如果 x 等于 y 并且 x 是 xs 的一个元素,则对于 xs 中的每个 x,否则 x 为零”。但是您希望为 x+y+xs 中的每个 x 完成它!您还以两种方式使用名称“x”,既是在函数参数的解构中,也是作为列表推导中的变量。

编辑:

现在我明白你的意思了。您只需将该显式递归添加到您已有的内容中。

twoAdjThenThirdZero [] = []
twoAdjThenThirdZero [x] = [x]
twoAdjThenThirdZero (x:y:xs) 
  | x == y && x `elem` xs = x : y : twoAdjThenThirdZero [if z == x then 0 else z | z <- xs]
  | otherwise             = x : twoAdjThenThirdZero (y:xs)

我希望这对您有意义,如果没有,我会尝试进一步解释!

编辑:

phynfo 发布了我所写内容的稍微简单的版本!

于 2012-10-07T19:37:59.003 回答