Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 当达到条件时,获取无限序列中的数字计数_F# - Fatal编程技术网

F# 当达到条件时,获取无限序列中的数字计数

F# 当达到条件时,获取无限序列中的数字计数,f#,F#,我想用函数式的方法来计算,我想有效地计算它们,所以我不想存储序列,只需遍历它并计算数字 let conjv2 x = let next n = match n%2 with |0 -> n/2 |_ -> n*3+1 Seq.initInfinite next |> Seq.takeWhile(fun n -> n > 1) |> Seq.length 这不起

我想用函数式的方法来计算,我想有效地计算它们,所以我不想存储序列,只需遍历它并计算数字

let conjv2 x =
    let next n = match n%2 with
                 |0 -> n/2
                 |_ -> n*3+1
    Seq.initInfinite next
    |> Seq.takeWhile(fun n -> n > 1)
    |> Seq.length
这不起作用,对于任何正数都返回0,这是3n+1猜想,我发现很难有效地计算它们,这段代码工作正常,但我想用函数的方式来计算:

let conj x =
    let mutable ansa = x
    let mutable cycles = 1
    while ansa > 1 do
        cycles <- cycles+1
        ansa <- match ansa%2 with
                |0 -> ansa/2
                |_ -> ansa*3+1
    cycles
let conj x=
设可变ansa=x
设可变圈=1
而ansa>1
周期ansa*3+1
周期

该示例的关键问题是您使用的是
Seq.initInfinite
而不是
Seq.unfold

  • Seq.initInfinite
    调用指定函数,将元素的索引作为参数(0、1、2、…)
  • Seq.unfold
    使用上一次迭代生成的状态调用指定函数
请注意,您的代码也没有使用参数
x
,因此您的函数最终是
'a->int
,而不是您所期望的
int->int
——这很好地表明存在错误

要解决此问题,请尝试以下方法:

let conjv2 x =
    let next n = match n%2 with
                 |0 -> n/2
                 |_ -> n*3+1
    Seq.unfold (fun st -> let n = next st in Some(n, n)) x
    |> Seq.takeWhile(fun n -> n > 1)
    |> Seq.map (fun v -> printfn "%A" v; v)
    |> Seq.length
传递给
unfold
的函数需要返回一个带有新状态的选项&一个要发出的值。为了生成无限序列,我们总是返回
Some
,并且发出的值是中间状态


这将返回比原始的
conj
小2的值,因为
conj
以1开始(而不是0),并且它还计算最后一个值(在此,我们在
ansa=1
之前停止)。因此,您需要在结果中添加2。

Seq.unfold(fun st->Some(st,next st))x这很好,但添加了第一个元素,这正是我需要的,但除此之外,谢谢。但是对于效率问题,这仍然比conj慢得多。是否有方法在遍历元素时使序列计数,而不是保存它们然后执行.length?如果在函数中保留“|>Seq.map(fun v->printfn”%a“v;v'),则速度会变慢。我打赌Tomas添加它是为了观察序列的展开,但这不是必需的。