我是Haskell的新手,我找到了一些练习的例子,但不知道如何处理它们。
我需要将"abcd"
分成子序列。
为:
["",a,b,c,d,ab,ac,ad,bc,bd,cd,abc,abd,bcd,acd,abcd]
我发现我必须使用子序列函数。
subsequences :: [a] -> [[a]]
我该怎么办?
答案 0 :(得分:6)
您可以按照建议subsequences
进行操作,看一下示例:
import Data.List
subsequences "abcd"
<强>输出:强>
["","a","b","ab","c","ac","bc","abc","d","ad","bd","abd","cd","acd","bcd","abcd"]
注意: subsequences
不对输出进行排序。但是,如果您想要排序的输出,可以使用以下内容:
import Data.List
import Data.Function
sortBy (compare `on` length) $ subsequences "abcd"
或强>
import Data.List
import GHC.Exts
sortWith length $ subsequences "abcd"
<强>输出:强>
["","a","b","c","d","ab","ac","bc","ad","bd","cd","abc","abd","acd","bcd","abcd"]
点击此处了解更多信息:
答案 1 :(得分:1)
这是一个简单的递归任务。
假设您有一个子列表的子序列列表。如何生成较长列表的子序列列表?
我建议将子序列列表按其长度分成子序列列表。所以你有[[subsequences length 0],[subsequences length 1],...]
。很容易看出,通过在较短的子序列中附加一个元素可以产生更长的子序列:[[subsequences length 0],[subsequences length 0 plus one element]++[subsequences length 1],[subsequences length 1 plus one element]++[subsequences length 2],...]
。
要对齐不同长度的子序列列表,请在子序列列表中添加一个空列表。然后将一个元素附加到较短的子序列,并与较长的子序列列表连接。
addoneall x xs = zipWith ((++) . (map (x:))) ([]:xs) (xs ++ [[]])
现在
subsequences = concat . foldr addoneall [[[]]]
生成所有长度的子序列列表 - foldr
通过将一个元素附加到较短输入的子序列列表来生成子序列列表。然后concat
将不同长度的子序列列表连接成一个。
Prelude Data.List> subsequences "abcd"
["","a","b","c","d","ab","ac","ad","bc","bd","cd","abc","abd","acd","bcd","abcd"]