在SML中制作星形三角形

时间:2018-09-23 20:50:55

标签: recursion sml smlnj

我刚刚开始使用SMLNJ进行编码,并且在制作以三角形星形模式返回字符串的程序时遇到了一些麻烦。例如,triangle(5)应该输出:

*****
****
***
**
*

到目前为止,我的代码是:

fun triangle(x) =  
    if (x = 0) then "\n"  
    else   
        let  
            fun makeTriangle(n) =  
                if(n = 0) then "\n" else "*"^makeTriangle(n-1);  
        in  
            makeTriangle(x);  
        end  
        triangle(x-1)  

我收到错误“ triangle.sml:9.3错误:语法错误:插入EQUALOP”。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您的代码至少存在两个问题:

首先,存在一个简单的运算符优先级问题:

if(n = 0) then "\n" else "*"^makeTriangle(n-1)

解析为

(if(n = 0) then "\n" else "*") ^ makeTriangle(n-1)

不是您想要的

if(n = 0) then "\n" else ("*" ^ makeTriangle(n-1))

解决方案是放入所需的括号。

另一个问题是函数底部的漏线triangle(x-1)。它与上面的代码无关。如果您打算将其连接到函数调用makeTriangle(x)的结果,则需要进行显式连接。在end之后的函数定义中实际上不应该包含任何内容,因为end终止了else部分。

一个小问题:由于您的函数makeTriangle插入了"\n",因此您的代码(固定后)在三角形的底部将有两个 "\n"。如果那不是您想要的,也许您可​​以考虑基本情况(n=0)。

答案 1 :(得分:1)

由于John已经解释了您的代码中的一些问题,并且由于这似乎是一种练习,因此您可以通过以下两种方式不同地解决它:

  1. 使用模式匹配来递归:

    fun repeat (0, _) = []
      | repeat (n, x) = x :: repeat (n-1, x)
    
    fun triangle 0 = ""
      | triangle n = implode (repeat (n, #"*")) ^ "\n" ^ triangle (n-1)
    
  2. 有一个名为List.tabulate的库函数,其中repeat是特例:

    fun repeat (n, x) = List.tabulate (n, fn _ => x)
    

    但是实际上,triangle本身非常适合List.tabulate

    fun triangle n =
        concat (List.tabulate (n, fn i => implode (repeat (15 - i, #"*")) ^ "\n"))