【发布时间】:2019-12-15 11:25:15
【问题描述】:
我正在为advent of code 2018(剧透警告)的问题寻找解决方案,我需要一个函数,该函数接受一个字符串(或一个char list)并删除每一对他们反应时的字符。该练习描述了“聚合物”中的两个字符或“元素”,当它们是相同的字母但仅大小写不同时会发生反应;所以从AbBc 开始会留下Ac。请记住,在一个反应之后,两个字符可能会彼此相邻,而不是以前,并引起新的反应。
我想我可以通过使用只处理前两个字符并递归调用自身的递归函数来解决这个问题,但由于输入字符串很大,这会导致stackoverflow exception:
let rec react polymer =
match polymer with
| [] -> []
| [x] -> [x]
| head::tail ->
let left = head
let right = List.head tail
let rest = List.tail tail
// 'reacts' takes two chars and
// returns 'true' when they react
match reacts left right with
// when reacts we go further with
// the rest as these two chars are
// obliterated
| true -> react rest
// no reaction means the left char
// remains intact and the right one
// could react with the first char
// of the rest
| false -> [left] @ react tail
然后,只是试图解决这个练习以获得单元测试的正确答案,我试图强制执行它,但这很快就变得一团糟,现在我有点卡住了。我正在自学f#,所以欢迎任何指点。谁能以功能的方式解决这个问题?
【问题讨论】:
-
尾递归是避免 stackoverflow 的一种方法。另外我认为你可以像这样
| left::right::tail ->左右模式匹配
标签: recursion f# stack-overflow tail-recursion