Avoid stackoverflow when recursively dismantling a string
我正在为代码2018年(扰流器警报)出现的问题寻求解决方案,其中我需要一个函数,该函数需要一个字符串(或
我认为我可以通过使用仅处理前两个字符并递归调用自身的递归函数来解决此问题,但是由于输入字符串很大,因此会导致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
然后,我只是想解决这个问题以针对单元测试找到正确的答案,我不得不进行此操作,但这很快就变得一团糟,现在我有点卡住了。我正在自学
您可以通过重写函数以使用尾部递归来避免堆栈溢出,这仅意味着递归调用应该是要执行的最后一个操作。
执行
您可以通过添加另一个函数参数使其尾部递归,该参数通常称为
我也将附录
1 2 3 4 5 6 7 8 | let rec react acc polymer = match polymer with | [] -> acc | [x] -> x::acc | left::right::rest -> match reacts left right with | true -> react acc rest | false -> react (left::acc) (right::rest) |
您也可以使用防护代替嵌套的
1 2 3 4 5 6 7 8 9 10 | let rec react acc polymer = match polymer with | [] -> acc | [x] -> x::acc | left::right::rest when reacts left right -> react acc rest | left::rest -> react (left::acc) rest |