繁体   English   中英

查找链表F#的总和

[英]Find sum of linked list F#

如何使用F#中的函数查找链表的元素总和?

F#具有内置的“链接列表”(通用)类型-仅称为list ,并且已经具有计算总和的功能:

let list1 = [2; 3; 5]
List.sum list1

可以使用递归函数编写对列表的任意操作:

let rec sum l = 
  match l with
    | [] -> 0
    | head::tail -> head + (sum tail)

但在大多数情况下,使用内置的fold功能就足够了:

let sum l =
  List.fold (fun total element -> total + element) 0 l

还要注意,上面的“天真”递归函数不是尾递归 ,因此当应用于非常长的列表时,它将崩溃。 尾递归的实现将是这样的:

let sum l =
  let rec sumAcc acc l = 
    match l with
      | [] -> acc
      | head::tail -> sumAcc (acc+head) tail
  sumAcc 0 l

基本上就是fold

(如果有人不知道F#落在此页面上,我会添加此答案-他/她可能对F#中的列表支持有误解)

let rec sum a = 
    match a with
    |Nil -> 0
    |Link(s,t) -> s+(sum (!t))

我尝试了您的示例,但它不起作用,因此我做了修复。

type lists = Nil | Link of (int * (lists ref))

let list1 = Link(3, ref (Link (2, ref Nil)))
let list2 = Link(6, ref (Link (4, ref Nil)))
let list3 = Link(9, ref (Link (6, ref Nil)))

let rec sum = function      // or  let rec sum list = match list with
    | Nil              -> 0
    | Link(head, tail) -> head + sum !tail

您不需要定义Integer of int ,如果要这样做,则必须用Integer标记所有数字

仅出于完整性考虑:

let sum l =
   l 
   |> List.reduce (+)

也可以解决问题。 类型推断将把l推断为一个int列表,因此,如果需要其他数字类型,则可以执行此操作(例如,一个long列表):

let sum (l:list<int64>) =
   l 
   |> List.reduce (+)

或这个:

   let inline sum l =
      l
      |> List.reduce (+)

内联将使sum函数通用化,以在提供名为“ +”的静态函数的任何类型上工作。 要使用它,您将具有以下代码:

let mylist = [1;2;3;4]
let sumOfMyList = sum mylist;;

我还要说,根据我的经验,使用列表折叠和相关函数比滚动自己的递归函数更好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM