string - Haskell 使用 exeptions 旋转字符串
问题描述
我是 Haskell 的新手,我正在尝试将一个字符向右移动一个字符,并且最后一个字符将始终是第一个字符,并且它将返回一个字符串。
例如:shiftString "abcd" = "dabc"
但是编译器不同意我的观点,有人可以帮我解决这个问题吗?
shiftString :: String -> String
shiftString x = take (length x) $ iterate rot1 x
where rot1 = drop 1 x ++ take 1 x
另外,我想在这之后检查两个字符串,如果其中一个是应用 shiftString 一次或多次的结果,则返回 True,我该如何使用它来做到这一点?如:
isShifted :: String -> String -> Bool
解决方案
Haskell 中的AString
只是Char
s 的列表 - 所以你可以使用简单的模式匹配来做到这一点:
shiftString' :: String -> String
shiftString' (firstChar:restChars) = restChars ++ [firstChar]
shiftString' [] = []
现在,如果你尝试这个,它会做与你想要的相反的事情 - 但有一个技巧:我们将字符串反转两次:
shiftString :: String -> String
shiftString = reverse . shiftString' . reverse
这应该够了吧
修复你的:
我认为你只需要rot1
(它与我的相同shiftString'
)以及上面的反向技巧
或者 - 修复你的更多:
我猜你尝试迭代rot1
更多次,然后放弃其余的 - 这也有效:
shiftS cs = head $ drop (length cs - 1) $ iterate rot1 cs
rot1 cs = drop 1 cs ++ take 1 cs
请注意,它iterate
为您提供了一个字符串列表(旋转越来越多)-我删除了第一个字符串(n-1
其中n
= 输入的长度),它再次给了我一个列表(您的版本中出现了一个类型错误)并占据了主导地位,因为我只想要String
这个列表中的第一个。
对于您isShifted
,您可以重用iterate
with rot1
(无需关心订单) - 这次length cs
从这里获取,然后检查您的其他输入是否是此列表的元素:
isShifted cs cs' = cs `elem` take (length cs) (iterate rot1 cs')
例子:
Prelude> isShifted "abcd" "cdab"
True
Prelude> isShifted "abdc" "cdab"
False
请注意,您不能只使用iterate rot1 cs'
而没有采取 - 考虑一下然后尝试会发生什么;)(提示:当您的输入转移时它会起作用-但如果它们不是,您会遇到麻烦 - 为什么?)
推荐阅读
- c# - DataGridView 生成 IndexOutOfRangeException
- jquery - 通过ajax提交多个表单
- opengl-es - 为什么在使用 gl.polygonOffset 时需要因子?
- python - 关于python数据库编程的查询
- angular - 如何从子组件中过滤父组件中的可观察对象?
- java - 错误:在类 testPackage.Method1 中找不到主要方法
- javascript - 获取 JS 中的所有 .m4a 文件
- python - 使用非 JSON 格式的表单数据抓取 ajax 调用
- javascript - Sticky Bootstrap 列应以父/内容结尾
- android - Android Studio 使用 Dagger 2 将依赖项注入到动态创建的片段中