2009-09-16 3 views
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, когда остановка или как сбросить его до начала.

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

ответ

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] 

Странно представлять фундаментально 2d-структуру таким образом. Почему не последовательность последовательностей:

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. карты и т. д., чтобы сделать Seq.

+0

Спасибо, я закончил с первой конструкцией. Я хочу, чтобы иметь возможность фильтровать последовательность всех этих чисел. Возможно, будет возможно отфильтровать второе «измерение» этих последовательностей, однако мне это кажется более легким. – esac

3

Я не могу думать о многих случаях, когда я предпочел бы 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]] 
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]] 
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 
Смежные вопросы