在 SML 中反转字符串的想法
Ideas for reversing strings in SML
我是 SML 的新手,对 C/C++ 有一些了解。我一直在尝试编写一个名为 reverseString 的函数,它接收要反转的字符串。非常简单。使用辅助函数,我能够编写一个函数来反转任何给定的字符串,并在结果中添加一个额外的字符。例如:
- reverseString("hello");
val it = "ollehh" : string
任何关于如何克服这个障碍的帮助都将非常有帮助。请记住,我正在尝试在没有任何附加功能的情况下实现该功能(即,在我的损坏实现中未使用的功能):
fun reverseAux(s:string, i:int) : string =
if i = 0 then str(String.sub(s, 0))
else str(String.sub(s, i-1)) ^ reverseAux(s, i-1);
fun reverseString(s:string) : string =
reverseAux(s, size(s));
除了我的评论之外,一旦您了解了模式匹配,这是一个更简单的解决方案:
fun helper [] = []
| helper [x] = [x]
| helper (l::ls) = (helper ls) @ [l];
fun reverse s = implode (helper (explode s));
explode
和 implode
是分别将 string
转换为 char list
的函数,反之亦然。列表比字符串更容易遍历。
你可以做 explode,然后 foldl 然后 implode:
fun reverse s = implode (foldl op:: [] (explode s));
被接受的答案(值得被接受)解释了如何从头开始做——这在您开始时是个好主意,但它涉及 @
,这是一个有点昂贵的操作(请参阅 this,了解关于看似线性算法如何在幕后变成二次函数的精彩讨论)。有一种方法可以避免它,尽管解释它有点复杂(Google "tail recursive reverse" 如果您有兴趣)。相反,内置函数 rev
已经实现了高效的列表反转。使用它,连同内置的组合运算符 o
可以允许在一行中创建 reverseString
:
val reverseString = implode o rev o explode;
请注意,我使用的是 val
而不是 fun
。组合是 returns 其他函数的高阶函数,我 使用 组合直接创建我想要的函数,而不是从头开始定义它。将大量内容打包到一行代码中的能力是函数式编程的主要优势之一。在这种情况下,它使用 composition 是一个链接运算符,并且从右到左读取。它说要反转一个字符串,你应该首先将它分解成一个列表,然后反转升力,然后将它内爆成一个字符串。
我是 SML 的新手,对 C/C++ 有一些了解。我一直在尝试编写一个名为 reverseString 的函数,它接收要反转的字符串。非常简单。使用辅助函数,我能够编写一个函数来反转任何给定的字符串,并在结果中添加一个额外的字符。例如:
- reverseString("hello");
val it = "ollehh" : string
任何关于如何克服这个障碍的帮助都将非常有帮助。请记住,我正在尝试在没有任何附加功能的情况下实现该功能(即,在我的损坏实现中未使用的功能):
fun reverseAux(s:string, i:int) : string =
if i = 0 then str(String.sub(s, 0))
else str(String.sub(s, i-1)) ^ reverseAux(s, i-1);
fun reverseString(s:string) : string =
reverseAux(s, size(s));
除了我的评论之外,一旦您了解了模式匹配,这是一个更简单的解决方案:
fun helper [] = []
| helper [x] = [x]
| helper (l::ls) = (helper ls) @ [l];
fun reverse s = implode (helper (explode s));
explode
和 implode
是分别将 string
转换为 char list
的函数,反之亦然。列表比字符串更容易遍历。
你可以做 explode,然后 foldl 然后 implode:
fun reverse s = implode (foldl op:: [] (explode s));
被接受的答案(值得被接受)解释了如何从头开始做——这在您开始时是个好主意,但它涉及 @
,这是一个有点昂贵的操作(请参阅 this,了解关于看似线性算法如何在幕后变成二次函数的精彩讨论)。有一种方法可以避免它,尽管解释它有点复杂(Google "tail recursive reverse" 如果您有兴趣)。相反,内置函数 rev
已经实现了高效的列表反转。使用它,连同内置的组合运算符 o
可以允许在一行中创建 reverseString
:
val reverseString = implode o rev o explode;
请注意,我使用的是 val
而不是 fun
。组合是 returns 其他函数的高阶函数,我 使用 组合直接创建我想要的函数,而不是从头开始定义它。将大量内容打包到一行代码中的能力是函数式编程的主要优势之一。在这种情况下,它使用 composition 是一个链接运算符,并且从右到左读取。它说要反转一个字符串,你应该首先将它分解成一个列表,然后反转升力,然后将它内爆成一个字符串。