我刚刚开始使用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”。任何帮助将不胜感激。
答案 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已经解释了您的代码中的一些问题,并且由于这似乎是一种练习,因此您可以通过以下两种方式不同地解决它:
使用模式匹配来递归:
fun repeat (0, _) = []
| repeat (n, x) = x :: repeat (n-1, x)
fun triangle 0 = ""
| triangle n = implode (repeat (n, #"*")) ^ "\n" ^ triangle (n-1)
有一个名为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"))