Sml 不反转列表的标准ML回文

Sml 不反转列表的标准ML回文,sml,palindrome,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 symmetr

我是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;
fun对称(i,n,inlist)=
如果List.nth(inlist,i-1)=List.nth(inlist,n-i)
那是真的
其他的
错误的
有趣的回文(n,inlist)=
允许
val i=参考1
在里面
虽然我不知道(
如果对称(!i,!n,!inlist)=false
那就错了
else()
i:=!i+1
)
符合事实的
终止

我只在有趣的回文中出错,但我自己无法修复。

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

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
以下是对您的代码的一些反馈:

<> >自然地,考虑使用递归而不是迭代。

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

    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
    
    可以写成

    if not (A)
    then false
    else B
    
    可以进一步改进为

    if A
    then B
    else false
    
    这和

    A andalso B
    
    因此,道德是:

  • 而不是
    A=false
    ,写
    而不是
    A=true
    (写
    A
  • 如果。。。然后else
  • 或else
    的一些组合。也就是说,当结果类型为bool时,if-then-else是不必要的(但如果逻辑非常复杂,您可能仍然喜欢它)

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

    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
    
    以下是对您的代码的一些反馈:

    <> >自然地,考虑使用递归而不是迭代。

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

    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
    
    可以写成

    if not (A)
    then false
    else B
    
    可以进一步改进为

    if A
    then B
    else false
    
    这和

    A andalso B
    
    因此,道德是:

  • 而不是
    A=false
    ,写
    而不是
    A=true
    (写
    A
  • 如果。。。然后else
  • 或else
    的一些组合。也就是说,当结果类型为bool时,if-then-else是不必要的(但如果逻辑非常复杂,您可能仍然喜欢它)

  • 如果禁止反转列表的限制旨在禁止使用内置的
    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;
    

    如果禁止反转列表的限制旨在禁止使用内置的
    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;
    

    “I Get errors”不是一个非常有用的错误描述,但是表达式不能同时包含类型
    bool
    false
    )和类型
    单元(
    ()
    )。你似乎陷入了一种命令式的心态;考虑避免引用和使用递归而不是循环。谢谢您的建议。现在,我只使用递归完成了回文。我刚开始函数式编程只有几天时间。以前,我从事Java、Ruby和其他类似语言的工作。使用ML编程对我来说是一种非常特殊的经历。“我犯了错误”不是一种非常有用的错误描述,但是表达式不能同时具有类型
    bool
    false
    )和类型
    单元(
    ()
    )。你似乎陷入了一种命令式的心态;考虑避免引用和使用递归而不是循环。谢谢您的建议。现在,我只使用递归完成了回文。我刚开始函数式编程只有几天时间。以前,我从事Java、Ruby和其他类似语言的工作。用ML编程对我来说是一次非常特殊的经历。