我需要一个函数,该函数查找实现List.fold
模块的列表的最小元素。我知道我可以使用List.min,但是对于本练习,我需要将其设为List.fold。到目前为止,我有:
let findMin list min = function
| [ ] -> min
| head::tail -> list |> List.fold( fun acc -> min) //missing conditional inside fold to determine min
我不习惯函数式编程,通常在Java中我会做这样的事情:
public int getMin (){
int min = head.data;
Node curr = head.next;
while (! ( curr == NULL ) ){
if ( curr.data < min)
min = curr.data;
curr = curr.next;
}
return min;
}
但是由于F#使用不可变常量,所以我无法重新分配min。我发现了用于对列表中的元素进行计数或求和的fold示例,但没有一个示例可以找到最小或最大元素。我在模块内部的条件逻辑方面遇到了麻烦,如果有人可以帮助我,我将不胜感激。预先谢谢你。
答案 0 :(得分:1)
您不需要处理输入列表为空的情况,因为在这种情况下List.fold
返回初始值。通常,我们将System.Int32.MaxValue
作为初始值。
这是长版代码:
let min a b = if a < b then a else b
let minOfList initialValue theList =
theList
|> List.fold
(fun currentMin x ->
let newMin = min currentMin x
newMin)
initialValue
let result = minOfList System.Int32.MaxValue [34; -1; 21; 99]
printfn "%d" result // -1
以及短版代码:
let min a b = if a < b then a else b
let minOfList = List.fold min
let result = minOfList System.Int32.MaxValue [34; -1; 21; 99]
printfn "%d" result // -1
答案 1 :(得分:0)
折叠的概念很简单:在一个列表上迭代一个名为folder
的函数。在每个调用中,folder
函数从列表中接收一个元素和一个状态,并返回更新后的状态。
这与命令式代码非常相似:正在遍历一个列表,从列表中接收一个元素和变量min
的旧值,并且在每次迭代之后,您都有一个新值{{1} }。命令式编程的区别在于min
函数不会更改状态,而是收到一个并返回另一个,您可以想象是否喜欢folder
在内部更改变量。
折叠的签名是:
List.fold
第一个参数是文件夹函数,第二个参数是初始状态,第三个参数是元素列表。结果将是最后一个状态。
因此您的List.fold :
folder: 'State -> 'T -> 'State ->
state : 'State ->
list : 'T list
-> 'State
函数应如下所示:
folder
和您的let folder min currData = ...
函数应如下所示:
minimum
您这样称呼它:
let minimum ls =
ls
|> List.fold folder initial
关于如何处理初始值以及列表为空时会发生什么,还存在一些问题。但是我会把那些留给你。
希望这会有所帮助。
答案 2 :(得分:0)
您可以使用累加器作为通常将最小值分配给的值。
对于数组的每个项目,fold将累加器和当前项目馈入给定的函数。该函数返回的所有值都将成为新的累加器值。
使用内置的min
函数,您可以编写
let findMin list = List.fold min System.Int32.MaxValue list
min
是应用于每个项目和累加器的功能
System.Int32.MaxValue
是累加器的原始值,即种子
您也可以使用List.reduce
,这是同一件事,但是它使用列表的第一个元素作为种子。
let findMin list = List.reduce min list
理想情况下,您可以将其包装在处理空数组的情况下,因为fold
将返回种子值,而reduce
将引发异常。
答案 3 :(得分:0)
感谢大家的帮助,以澄清一些概念。这是最后运行的代码段,输入验证已在main函数中完成。
//这是文件夹函数List.fold调用,接收当前的分钟和项目
让文件夹a b =如果a
//接收列表并使用List.fold模块返回最小值
折叠列表= List.fold(有趣的权限->文件夹权限)(List.head列表)列表