如何在保留字符串形状的同时旋转字符串列表中的字母?
Posted
技术标签:
【中文标题】如何在保留字符串形状的同时旋转字符串列表中的字母?【英文标题】:How to rotate letters in a list of strings while preserving the strings' shapes? 【发布时间】:2022-01-03 02:59:03 【问题描述】:我正在尝试编写一个函数join :: [[a]] -> [[a]]
,它将列表中列表的最后一个字符与列表中列表的第一个字符连接起来。
join ["m"] = ["m"]
join ["a","b","c"] = ["b","c","a"]
join ["goodday", "world", "i", "love", "haskell"] = ["ooddayw","orldi","l","oveh","askellg"]
join ["the", "catcher", "in", "the", "rye"] = ["hec","atcheri","nt","her","yet"]
我正在尝试编写一个仅使用 Haskell 中的基本函数(没有库函数)并且仅使用递归的代码。
但是,我似乎无法实现一段正常工作的代码。这是我到目前为止的代码:
join :: [[a]] -> [[a]]
join [[a]] = [[a]]
join (n:ns:nss) | null nss == False = ((i n ns) : k (ns:nss))
| otherwise = []
可以这样做吗?
【问题讨论】:
将问题分成更小的部分可能更容易。例如,从一个函数开始,该函数仅从每个子列表[[a]] -> ([[a]], [a])
中提取第一个元素。从那里您可以考虑旋转提取的列表,然后将元素重新连接到每个相应子列表的末尾。
我建议不要使用名称 join
,因为这是 Prelude 中可用的重要功能的名称。
@RobinZigmond 要是真的在 Prelude 就好了
@amalloy - 哎呀,所以你是对的,它不是。我可以发誓它是:/
【参考方案1】:
这是一个具有高阶函数的解决方案,在整个数据-操作范式中工作:
import Control.Applicative (liftA2)
import Data.List (unfoldr)
import Control.Arrow ( (>>>) )
rotateds :: [[a]] -> [[a]]
rotateds =
map (splitAt 1) -- 1., 2.,
>>> concatMap (\(a,b) -> [a,b]) -- 3.,
>>> liftA2 (++) (drop 1) (take 1) -- 4.,
>>> unfoldr (Just . splitAt 2) -- 5.,
>>> takeWhile (not . null) -- 5.,
>>> map (\[a,b] -> (++) a b) -- 6.
它通过了你所有的测试。所以是的,这是可能的。它的工作原理是:
1. turn each sublist in the input [ [a,b,c,...] , [d,......] , ... ]
2. into a pair [ ([a],[b,c,...]) , ([d], [...]) , ... ]
3. splice'em in [ [a],[b,c,...] , [d], [...] , ... ]
4. move the first letter over [ [b,c,...] , [d], ........ [a] ]
5. and restore the structure back to how it was
by reconstituting the pairs [ [[b,c,...] , [d]], ........... ]
6. and appending them together [ [ b,c,... , d ], ........... ]
将其转换为直接手动递归是一项艰巨的任务留给***的学习者作为练习。
【讨论】:
毕竟调出not so torturous(但仍然使用一些take
、drop
和`++)。以上是关于如何在保留字符串形状的同时旋转字符串列表中的字母?的主要内容,如果未能解决你的问题,请参考以下文章