1

我想生成一个像乘法表一样的序列。因此,对于 1 的开始和 10 的停止,我正在寻找类似的序列

1, 2, 3, 4, 5, 6, 7, 8, 9, 10,  // 1*1 - 1*10
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, // 2*1 - 2*10
3, 6, 9, 12, ... // 3*1 - 3*10

这是我蹩脚的开始,但是我似乎无法弄清楚如何在到达停止点时干净地增加 j ,或者如何将 i 重置回开始。

let multable (start,stop) =
    (start,start)
    |> Seq.unfold(
        fun (i,j) ->
        Some(i*j, (i+1, j)))

let its = multable(1, 1)

let first10 = Seq.take 10 its
printf "%A" (Seq.to_list first10)  

这当然给了我 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

4

4 回答 4

4

我真的想不出在很多情况下我更喜欢Seq.unfold等效的列表理解:

> let multiplication n m = [for a in 1 .. n -> [for b in 1 .. m -> a * b ] ];;

val multiplication : int -> int -> int list list

> multiplication 5 5;;
val it : int list list =
  [[1; 2; 3; 4; 5]; [2; 4; 6; 8; 10]; [3; 6; 9; 12; 15]; [4; 8; 12; 16; 20];
   [5; 10; 15; 20; 25]]

有时 Array.init 方法也很有用:

> let multiplication n m = Array2D.init n m (fun n m -> n * m);;

val multiplication : int -> int -> int [,]

> multiplication 5 5;;
val it : int [,] = [[0; 0; 0; 0; 0]
                    [0; 1; 2; 3; 4]
                    [0; 2; 4; 6; 8]
                    [0; 3; 6; 9; 12]
                    [0; 4; 8; 12; 16]]
于 2009-09-16T22:27:00.670 回答
3

使用序列表达式:

let multable start stop = seq{
    for a = start to stop do
      for b = start to stop do
        yield a*b
}

输出:

> multable 1 3 |> Seq.to_list;;
val it : int list = [1; 2; 3; 2; 4; 6; 3; 6; 9]

以这种方式表示一个基本的二维结构是很奇怪的。为什么不是一个序列序列:

let multable2 start stop = seq {
    for a = start to stop do yield seq {
      for b = start to stop do
        yield a*b
    }
}

输出:

val multable2 : int -> int -> seq<seq<int>>

> multable2 1 3 |> Seq.to_list;;
val it : seq<int> list = [seq [1; 2; 3]; seq [2; 4; 6]; seq [3; 6; 9]]

如果您想“聪明”并避免乘法:

let multable4 start stop = seq {
    for a = start to stop do yield seq {
      let s = ref 0 in
      for b = start to stop do
        s:=!s+a
        yield !s
    }
}

在理解/序列表达式之外,我实际上没有看到任何好的预打包“从 a 到 b 的序列”,尽管显然有 [a..b] (列表)和 [|a..b|] (数组),你可以通过 Seq.unfold、Seq.map 等项目制作 Seq。

于 2009-09-16T22:22:39.913 回答
1
let Table r c =
    [for row in 1..r do
        yield [for col in 1..c do
                    yield row * col]]
printfn "%A" (Table 5 4)                    
// [[1; 2; 3; 4]; [2; 4; 6; 8]; [3; 6; 9; 12]; [4; 8; 12; 16]; [5; 10; 15; 20]]
于 2009-09-16T22:28:45.690 回答
0

这是使用序列的另一种方法:

let rec fromXToY x y =
  seq {
    if x <= y
    then yield x; yield! fromXToY (x + 1) y;
    else ()
  }

let scaledSequence factor items =
  Seq.map (fun x -> factor * x) items

let mulTable x y =
  let sequenceOfIntegersMultipliedByValue = (fun n -> scaledSequence n (fromXToY x y))
  let seqOfSeqOfValues = Seq.map sequenceOfIntegersMultipliedByValue (fromXToY x y)
  // Convert the sequence of sequences to a simple sequence of values
  Seq.fold Seq.append Seq.empty seqOfSeqOfValues
于 2009-09-19T07:33:57.517 回答