2017-02-08 2 views
1

Ich habe eine Funktion:Erstellen einer Funktion, die eine Liste von Vielfachen erzeugt ocaml

let rec multiply x ls = 
match ls with 
[] -> [] 
| h::tl -> (x * h) :: multiply x tl 

multiply 2 [1; 2; 3] = [2; 4; 6]

Ich möchte ein Funktion, die mehrfach von n ruft auf 0. ich halte Probleme wegen des Basisfall mit:

let rec multiply_all x ls = if x > 0 
then (multiply n ls) :: multiply_all (n-1) (ls) else ???? 

ich bin nicht sicher, was nach dem anderen zu setzen. Ich habe versucht, es

if x > 1 then (multiply n ls) :: multiply_all (n-1) (ls) else multiply all 1. 

zu machen, aber das funktioniert nicht.

Antwort

0

Nur eine andere Lösung:

let multiply_all n l = 
    let multiply n= List.map ((*) n) in 
    let rec aux i acc = 
    if i > n then acc 
    else aux (i+1) (multiply i l :: acc) 
    in 
    aux 1 [] 
;; 

Test:

# multiply_all 5 [1;2;3];; 
- : int list list = 
[[5; 10; 15]; [4; 8; 12]; [3; 6; 9]; [2; 4; 6]; [1; 2; 3]] 
1

Putting 1 dort funktioniert sicherlich nicht, da multiply_all eine Liste zurückgeben muss. Sie brauchen also eine Liste (von Listen von int), um dort zu setzen. Aber welche Liste sollte es sein?

Die kurze Antwort ist, dass in solchen einfachen Fällen die Liste, die Sie benötigen, normalerweise die leere Liste ist: [].

Als etwas längere Antwort können wir den Fall für multiply_all 0 in Bezug auf die beabsichtigten Ergebnisse von multiply_all 1, multiply_all 2 usw. betrachten und versuchen, ein passendes Muster zu finden. Wir wollen multiply_all so verhalten:

# multiply_all 2 [1;2;3];; 
- : int list list = [[2; 4; 6]; [1; 2; 3]] 
# multiply_all 1 [1;2;3];; 
- : int list list = [[1; 2; 3]] 

multiply_all mit einiger Anzahl N als erstes Argument So rufen sollte uns N eine Liste der Länge geben. Insbesondere sollte multiply_all mit N = 0 eine Liste der Länge 0 geben. Die Liste der Länge 0 ist die leere Liste.

Hier Ihre vollständige Definition lautet:

let rec multiply_all x ls = 
    if x > 0 then (multiply x ls) :: multiply_all (x-1) (ls) else [] 
-1

Zu allererst Ihre multiply Methode ist ziemlich ineffizient, da es nicht Schwanz rekursive ist. Darüber hinaus stellt die Standard-Bibliothek, die Sie mit Werkzeugen, die Art der Funktion zu erleichtern, zu schreiben:

let multiply n = List.map ((*) n);;; 
val multiply : int -> int list -> int list = <fun> 

multiply 5 [1;2;3];; 
- : int list = [5; 10; 15] 

Hinweis: Auch partielle Anwendung verwenden, wenn es nicht, Ihren Code nicht verschleiern.

Ab multiply_all, ich bin mir nicht sicher, wie man es ohne JaneStreet Core erreichen kann (siehe this question). Allerdings ist hier eine mögliche Implementierung mit Core:

open Core.Std;; (*Using Core*) 
let multiply_all n l = 
    let multiples = List.init n ~f:(fun x -> n-x) in (*This doesn't exist in Pervasives*) 
    List.map multiples ~f:(fun m -> multiply l m);; 
val multiply_all : int list -> int -> int list list = <fun> 

multiply_all 5 [1;2;3];; 
- : int list list = [[5; 10; 15]; [4; 8; 12]; [3; 6; 9]; [2; 4; 6]; [1; 2; 3]] 

Hoffe, es hilft. Ich werde diese Antwort mit meinen Ergebnissen über List.init aktualisiert halten.

+0

Jede Eingabe auf dem downvote, bitte? – RichouHunter

Verwandte Themen