haskell 按位置删除各种元素

zvms9eto  于 8个月前  发布在  其他
关注(0)|答案(2)|浏览(75)

我正在做一个课堂练习,经过一段时间的绞尽脑汁,我找到了理论上的方法来做它,但无法找出如何在Haskell中做。
这项工作是:
有一个列表xs,其中有n个不同的元素。列表xsn元素的组合将它们从m带到m(带有m <= n),是可以从原始n元素形成的所有可能的m元素集(没有重复)。
元素的顺序并不重要(这意味着"abc"被认为是与"bca"相同的组合)。
举例来说:

comb 0 "abcd" -> [""]
comb 3 "bcd" -> ["bcd"]
comb 2 "bcd" -> ["cd","bd","bc"]
comb 3 "abcd" -> ["bcd", "acd", "abd", "abc"]

定义一个函数comb,它接受一个自然数m和一个包含n个不同元素的列表xs
我能找到的唯一方法是,我需要一个值,它将我的“位置指针”pp,这样它将删除该指针之后的length xs - m元素,然后在递归调用中做m + pp,所以它“跳”到下一个位置。我将以一种伪Haskell的方式写一个例子:

m = 3   xs = "abcd"   * = pp

*abcd       *remove (length xs - m) after pointer
Solution:  "bcd"  

*Recursively jump pointer by (length xs - m):

"a*bcd"   ->   "acd"
"ab*cd"   ->   "abd"
"abc*d"   ->   "abc"
"abcd*"   ->   [""]

我真的很抱歉这种发明,我试图使用指针类比,因为我认为这是很容易看到它的方式,我用我的伪代码和Haskell的混合,因为不知道如何做它的另一种方式。

d8tt03nd

d8tt03nd1#

如何从列表中选择n元素?

comb :: Int -> [a] -> [[a]]

如果n为零,那么无论列表是什么,都只有一个没有元素的pick。

comb 0 _ = [[]]

否则,如果你的列表是空的,你根本没有选择。(注意这与上面的不同。

comb _ [] = []

否则,你的列表就有一个头和一个尾。选择如下。首先,你有所有的选择,包括头,然后所有的选择,不包括头。

comb n (x:xs) = withHead ++ withoutHead where

如何构建所有不包括头部的选择?这很简单,只需将函数递归地应用于列表的尾部。

withoutHead = comb n xs

包括头部的选择呢?这也很简单,只需将函数递归地应用于列表的尾部,但这次要将picks缩短一个元素。然后在每个拨片前面拍一下头。

withHead = map (x:) (comb (n-1) xs)
wsxa1bj1

wsxa1bj12#

基本上你可以做的就是每次选择一个元素,然后继续添加元素。
为了防止 * 对称 *,我们可以说,如果我们在位置 i 选择一个字符,我们只能选择位置 i 右侧的项目,所以这意味着我们将列表中的 * 其余 * 字符作为递归传递。
我们可以先构造一个helper函数,对于一个给定的列表[a],返回一个2元组[(a, [a])]的列表,其中包含选中的项和其余的项,所以:

pick :: [a] -> [(a, [a])]
pick [] = []
pick (x : xs) = … : …

在这里,我把填写部分作为练习。对于[1,4,2,5],它应该返回[(1, [4,2,5]), (4, [2,5]), (2, [5]), (5, [])],因为我们可以选择任何元素,并且每次在我们选择的元素的右侧都有一个剩余元素的列表,我们可以使用它来选择其他元素。
现在我们有了它,我们可以做一个递归函数来挑选 n 个元素。我们通过检查还有多少项目需要挑选来做到这一点。对于没有项目,我们返回一个单一的项目:空的名单。对于 n 个项目,我们选择一个项目并递归 n-1 个项目:

comb :: Int -> [a] -> [[a]]
comb 0 _ = [[]]
comb n xs = [x : zs | (x, ys) <- pick xs, zs <- comb (n - 1) ys]

我们可以进一步提升这个算法,只选择那些在选择后仍有 n-1 个元素的元素。我也把它作为一个练习。
因此,我们在这里 * 不 * 需要列表的长度,我们可以只选择元素。如果初始列表具有无限长,这甚至会产生结果:如果我们需要 m 个项目,它最终将返回 [x1,x2,...,xm-1,xn],并因此产生结果,尽管对于上述实现,它永远不会产生以 [x1,x3,...] 开头的结果。

相关问题