括号匹配F#
所以我试图用f#来找出字符串是否有匹配的括号。 i、 e:(abc)返回true,((hello)返回false,)返回false,等等 我(认为)正在做的是使用堆栈在列表中看到“(”并在看到“')”时弹出。如果字符串列表为空,则堆栈有项或没有项。如果有,则我说它无效,如果遇到“')”且堆栈为空,则它也无效。否则,它是一个有效字符串括号匹配F#,f#,F#,所以我试图用f#来找出字符串是否有匹配的括号。 i、 e:(abc)返回true,((hello)返回false,)返回false,等等 我(认为)正在做的是使用堆栈在列表中看到“(”并在看到“')”时弹出。如果字符串列表为空,则堆栈有项或没有项。如果有,则我说它无效,如果遇到“')”且堆栈为空,则它也无效。否则,它是一个有效字符串 // Break string let break_string (str:string) = Seq.toList str let isBalanced
// Break string
let break_string (str:string) =
Seq.toList str
let isBalanced (str:string) =
let lst = break_string str
let stack = []
let rec balance str_lst (stk:'a list)=
match str_lst with
| [] ->
if stk.Length > 0 then
false
else
true
| x::xs ->
if x = '(' then
balance (xs x::stack)
elif x = ')' then
if stack.Length = 0 then
false
else
stack = stack.tail
balance (lst, stack)
我对f#很陌生,所以我认为这可能是我想要的,但是我得到了错误信息:
“此表达式应具有bool类型,但此处具有'a list->bool'类型”
首先,这实际上意味着什么?
其次,既然它返回bool,为什么不起作用呢?类型检查器认为您忘记了
balance
的第二个参数。当你写这篇文章时:
balance (xs x::stack)
它的意思是“将balance
应用于(将xs
应用于x::stack
)”。你可能是这个意思:
balance xs (x::stack)
您的最后一个elif
似乎也缺少else
分支,并且行stack=stack.tail
看起来像是您试图分配给stack
。您不能这样做,因为stack
是一个不可变的变量。您可能需要平衡xs(List.tail stack)。其原理是,不给变量赋值,而是用新值调用函数
当然,你的想法是对的。通过将所有匹配项(字母是什么?堆栈上有什么?)折叠到一个匹配语句中,可以更加简洁。诀窍是将所有要查看的内容放入一个元组:
let isBalanced str =
let rec loop xs stack =
match (xs, stack) with
| '(' :: ys, stack -> loop ys ('(' :: stack)
| ')' :: ys, '(' :: stack -> loop ys stack
| ')' :: _, _ -> false
| _ :: ys, stack -> loop ys stack
| [], [] -> true
| [], _ -> false
loop (Seq.toList str) []
@rpax,请停止添加无用的tagslast调用应该是
balance lst stack
。这就是在F#中调用具有多个参数的函数的方式<代码>(a,b)语法创建元组。这同样适用于递归调用。好的,这似乎已经修复了这一部分;然而,它却在抱怨我的elif=')
不是一个傻瓜?它说它有uint。那elif
的else
在哪里?哦,哈哈。由于缺少else,这似乎是一个奇怪的错误。错误之所以说它应该是unit
,是因为没有else
的if
(或elif
)必须具有类型unit
。