F# - 从...中返回一个值

unk*_*656 4 iteration big-o f# loops

我有一组(随机)数字,我想决定任何给定的数字,数字是否是复合数字(意味着它可以由同一给定集合中的其他两个数字创建).
我的函数的数学定义:

在此输入图像描述

当前代码:

let task1 (M : seq<'T>, r : 'T) : bool =
    if not(Seq.exists((=) r) M) then
        failwith "nope!"
    else
        for s in M do
            for t in M do
                if s + t = r then
                    true         // error
        false
Run Code Online (Sandbox Code Playgroud)

问题:
我无法从我的迭代返回一个布尔值,当元素r已经被"发现"的两个元素的总和st.


我怎样才能尽可能有效地解决给定的问题?

如果有人发现运行时间小于O(n²)的算法,那么我也可以.
[所有被称为方法的速度也必须比O(n²)快]

The*_*ght 5

你无法做你想做的事情,因为F#是一种使用表达式而不是语句的语言.F#表达式总是计算为一个值(尽管该值可能是单位:) ().

您最初发布的代码无法编译,因为某些类型unit是预期的,这是因为您的if/then表达式没有else分支.考虑以下:

let a = if x > 5 then 10
Run Code Online (Sandbox Code Playgroud)

此代码将产生编译器错误,这很明显,因为a如果x不大于5,我们没有指定可能的整数值.

当然,这段代码会编译:

let a = if x > 5 then 10 else 5
Run Code Online (Sandbox Code Playgroud)

如果你提供和if不提供else,F#编译器将假定类型是单位,所以这也是有效的代码:

let a = if x > 5 then ()
Run Code Online (Sandbox Code Playgroud)

这是因为两种情况仍然只是返回unit,没有类型不匹配.

因为F#使用表达式,所以一切都必须可绑定到一个值.


无论如何,您可以通过使用嵌套Seq.exists语句来解决这个问题,这样您就可以检查每个值的组合.

let inline task1 items r =
    items |> Seq.exists (fun s ->
        items |> Seq.exists(fun t -> s + t = r))
Run Code Online (Sandbox Code Playgroud)

我已经改变了一些你的命名约定(这是F#函数参数的惯用语是camelCased)并且已经使你的函数inline可以在任何支持加法的类型上工作.