如何生成乘法表序列?

发布于 2024-08-04 18:52:11 字数 569 浏览 2 评论 0原文

我想生成一个像乘法表一样的序列。因此,对于 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

Here is my lame start at it 的序列,但是我似乎无法弄清楚如何在到达停止时干净地递增 j ,或者如何重置我回到起点。

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

I want to generate a sequence like a multiplication table. So for a start of 1 and a stop of 10 I am looking for a sequence like

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

Here is my lame start at it, however I can't seem to figure out how to cleanly increment j when the stop is reached, or how to reset i back to the start.

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)  

Which of course gives me 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

箹锭⒈辈孓 2024-08-11 18:52:11

我真的想不出很多情况下我更喜欢 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]]

I can't really think of many cases where I'd prefer Seq.unfold over an equivalent list comprehension:

> 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]]

Occasionally the Array.init methods are useful too:

> 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]]
亣腦蒛氧 2024-08-11 18:52:11

使用序列表达式:

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。

Use a sequence expression:

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

Output:

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

It's weird to represent a fundamentally 2d structure in this fashion. Why not a sequence of sequences:

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

Output:

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]]

If you want to be "clever" and avoid multiplication:

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
    }
}

I don't actually see any nice prepackaged "sequence from a to b" outside of comprehensions/sequence expressions, although there's obviously [a..b] (list) and [|a..b|] (array) which you can project through Seq.unfold, Seq.map, etc. to make a Seq.

生死何惧 2024-08-11 18:52:11
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]]
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]]
2024-08-11 18:52:11

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

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

Here's another way to use sequences:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文