haskell - 在所有可能的“子词”中拆分一个词 - 所有可能的组合 W/O 导入
问题描述
我试图在不使用任何导入的情况下以下列方式获取单词的所有可能组合:
例如...
Input: Bang
Output: [['B','ang'], ['Ba','ng'], ['Ban','g'], ['B','a','ng'], ['B','an','g'], ['Ba','n','g'], ['B','a','n','g']]
这个问题一直困扰着我一段时间,我似乎无法找出一个算法来做到这一点..
下面的代码是我所做的,但这给出了字符串的所有可能组合,但不是我需要的方式。
我试图在 haskell 中实现这个 python 代码,但我无法完成它。它基本上是同样的问题,但你在haskell中没有循环。
下面代码的输出是......
["太阳","su","s","un","u","n"]
并不是
[["s","un"],["s","u","n"],["su","n"]]
-----------------------------------------------------
substring :: String -> [String]
substring [] = []
substring xs = subs xs ++ substring (tail xs)
where
subs xs = foldl step [] xs
step [] a = [[a]]
step acc a = (head acc ++ [a]) : acc
---------------EXAMPLES OF EXPECTED RESULTS BELOW----------------------------------
Input: Bang
Output: [['B','ang'], ['Ba','ng'], ['Ban','g'], ['B','a','ng'], ['B','an','g'], ['Ba','n','g'], ['B','a','n','g']]
Input: Sun
Output: [["s","un"],["s","u","n"],["su","n"]]
解决方案
请注意,您尝试的类型签名是错误的。您想要子词拆分的所有组合,这是一个字符串列表,但您的类型只是一个字符串列表列表。
这将起作用:
onHead :: (a -> a) -> [a] -> [a]
onHead _ [] = []
onHead f (x:xs) = f x:xs
combos :: [a] -> [[[a]]]
combos [] = [[]]
combos [x] = [[[x]]]
combos (x:xs) = [([x]:), onHead (x:)] <*> combos xs
onHead
应该是不言自明的:在列表的头部执行给定的功能。combos
递归如下:字符串的子词是其尾部的子词,每种都有两种可能性:头部是它自己的子词,或者它被附加到第一个子词的开头。
更新:这是另一种(IMO 清洁器)方法:
combos :: Foldable t => t a -> [[[a]]]
combos = foldr (concatMap . go) [[]]
where go x l = ([x]:l):case l of
[] -> []
h:t -> [(x:h):t]
它使用与上述相同的技术,只是实现更简洁。
推荐阅读
- jarsigner - 是什么导致 jarsigner 覆盖 MANIFEST.MF
- swift - Swift 4.1 无法将字符串转换为本地日期,总是返回 UTC 日期
- r - 具有重复元素的样本的 2 到 2 的排列
- ssh - TortoisePlink 致命错误
- javascript - 返回不工作和过于复杂的代码
- tfs - 需要 TFS 到 VSTS 迁移信息
- javascript - 请求在 WAMP 上被阻止,但在 XAMPP 上允许 CORS
- vba - 更改后运行 VBA 宏
- django - Django:重定向没有按预期工作
- javascript - 通过 Javascript (RDF4J Server REST API) 查询 GraphDB 时指定结果 MIME 类型