首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将递归函数从3条简化为2条

将递归函数从3条简化为2条
EN

Stack Overflow用户
提问于 2015-06-04 15:13:03
回答 2查看 418关注 0票数 2

我正在做一些关于F#的练习,我有一个函数来计算备用和:

代码语言:javascript
运行
复制
let rec altsum = function
    | []         -> 0
    | [x]        -> x
    | x0::x1::xs -> x0 - x1 + altsum xs;; 

val altsum : int list -> int

这个练习包括声明同一个函数,只使用两个clauses...but,如何做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-04 15:55:47

我的教条盒的答案是正确的和工作的!

但经过几次尝试,我找到了这个问题的最小和可读性的解决方案。

代码语言:javascript
运行
复制
let rec altsum2 = function
| [] -> 0
| x0::xs -> x0 - altsum2 xs

示例

代码语言:javascript
运行
复制
altsum2 [1;2;3] essentially do this:
1 - (2 - (3 - 0)

这是有点棘手,但工作!

OFF主题:

使用F#列表库解决问题的另一种优雅方法是:

代码语言:javascript
运行
复制
let altsum3 list = List.foldBack (fun x acc -> x - acc) list 0;;

在phoog的评论之后,我开始尝试用尾递归函数来解决这个问题:

代码语言:javascript
运行
复制
let tail_altsum4 list = 
    let pl l = List.length l % 2 = 0
    let rec rt = function    
        | ([],acc) -> if pl list then -acc else acc
        | (x0::xs,acc) -> rt (xs, x0 - acc)
    rt (list,0)

这也有点像tricky...substraction是不可交换的,不可能用List.rev (一个长的list...but,我找到了一个解决办法!)

票数 7
EN

Stack Overflow用户

发布于 2015-06-04 15:44:24

为了减少案例的数量,您需要将算法移回更接近原始问题的位置。问题是否定交替值,所以这就是你的解决方案应该做的。

代码语言:javascript
运行
复制
let altsum lst =
  let rec altsumRec lst negateNext =
    match lst with
    | [] -> 0
    | head::tail -> (if negateNext then -head else head) + altsumRec tail (not negateNext)
  altsumRec lst false
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30647694

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档