我有这个函数用于在ocaml中反转字符串但是它说我的类型错了。我不确定为什么或我能做什么:(
任何关于调试的提示也将非常感谢!
28 let reverse s =
29 let rec helper i =
30 if i >= String.length s then "" else (helper (i+1))^(s.[i])
31 in
32 helper 0
错误:此表达式具有char类型,但表达式需要类型 串
谢谢
答案 0 :(得分:8)
您的实现没有预期的(线性)时间和空间复杂度:它在时间和空间上都是二次的,因此它几乎不是所请求功能的正确实现。
字符串连接sa^sb
分配一个大小为length sa + length sb
的新字符串,并用两个字符串填充它;这意味着它的时间和空间复杂度在长度之和上是线性的。当您对每个字符迭代此操作一次时,您将获得二次复杂度的算法(分配的内存总大小和总副本数将为1+2+3+....+n
)。
要正确实施此算法,您可以:
分配一个预期大小的字符串,并使用输入字符串的内容将其变异,反转
创建一个由反向大小 - 一个字符串构成的string list
,然后使用String.concat
一次连接所有这些字符串(分配结果并仅复制字符串一次)
使用Buffer模块,该模块用于迭代地累积字符或字符串而不显示二次行为(它使用动态调整大小策略,使得添加char摊销的常量时间)
< / LI>第一种方法既是最简单也是最快,但是其他两种方法在你想要连接字符串的更复杂的应用程序中会变得更有趣,但是在一步中知道最终结果将会更简单。< / p>
答案 1 :(得分:4)
我认为错误信息非常清楚。表达式s.[i]
表示字符(字符串的i
字符)。但^
运算符需要字符串作为参数。
要解决此问题,您可以使用String.make 1 s.[i]
。此表达式提供包含单个字符s.[i]
的1个字符的字符串。
在OCaml中递归处理字符串并不是那么好,因为没有很好的方法来解构字符串(将其分解为部分)。反转列表的等效代码看起来更漂亮。值得的: - )
答案 2 :(得分:1)
您也可以使用第三方库来执行此操作。 http://batteries.forge.ocamlcore.org/已经实现了一个反转字符串的函数