标准ML Palindrome没有颠倒列表

时间:2016-05-09 17:47:33

标签: sml palindrome

我是SML的新手,也不太了解语法。

我正在练习检查回文而不反转列表。这是我的代码

fun symmetric(i,n,inlist) = 
if List.nth(inlist,i-1) = List.nth(inlist,n-i)
    then true
else
    false;

fun palindrome(n, inlist) = 
let 
    val i = ref 1
in
    while !i < n do (
        if symmetric(!i,!n,!inlist) = false
            then false
        else ()
        i := !i + 1
    )
    true
end;

我只在有趣的回文中遇到错误,但我自己无法解决。

2 个答案:

答案 0 :(得分:4)

您甚至可以在不将字符串转换为列表的情况下制作回文检查器:

fun palindrome s =
    let fun check i j =
            i >= j orelse
            String.sub (s, i) = String.sub (s, j) andalso
            check (i+1) (i-1)
    in check 0 (String.size s - 1) end

以下是您的代码的一些反馈:

  1. 当然,请考虑使用递归而不是迭代。

  2. 非功能性程序员的一个常见问题是,他们似乎只是为了副作用而连续执行许多语句。在函数式编程中,您非常依赖每个表达式的值来指导程序的结果。但 是一个;运算符,它可以像这样使用:

    fun palindrome s =
        let val i = ref 0
            val j = ref (String.size s - 1)
            val result = ref true
        in while !i < !j do
               (if String.sub (s, !i) = String.sub (s, !j)
                then (i := !i + 1 ; j := !j - 1)
                else (i := !j ; result := false))
         ; !result
        end
    

    但是,如果你想连续做多件事,那么let-expression就像;运算符一样整洁。

  3. 代码

    if A = false
    then false
    else B
    

    可以写成

    if not (A)
    then false
    else B
    

    可以进一步改进为

    if A
    then B
    else false
    

    完全相同
    A andalso B
    

    所以道德是:

    1. 而不是A = false,请写not A(而不是A = true,写下A)。
    2. 您始终可以使用if ... then <true/false> else <true/false>andalso的某种组合替换orelse。也就是说,当结果类型是 bool 时, if-then-else 永远不需要(但如果逻辑很复杂,你可能仍然喜欢它。)

答案 1 :(得分:3)

如果反对列表的限制旨在禁止使用内置rev而不是隐式反转列表的计算,则这里是基于堆栈的方法。我们的想法是将字符推入堆栈(表示为列表),然后将其弹出,并根据原始字符列表进行检查。如果堆栈或原始列表首先清空,或者弹出的项目与原始列表中的相应字符不匹配 - 它不是plalindrome

fun pushAll [] stack = stack
|   pushAll (x::xs) stack = pushAll xs (x::stack)

fun popCheck [] [] = true
|   popCheck [] _ = false
|   popCheck _ [] = false
|   popCheck (x::xs) (y::ys) = x = y andalso popCheck xs ys

fun palindrome s = 
    let val chars = explode s
        val stack = pushAll chars []
    in
        popCheck chars stack
    end;