Mi piacciono i puzzle f #, quindi ho preso una pugnalata a questo. Spero che ti piaccia.
let orgList = [(2, 1); (3, 2); (4, 2); (5, 3); (6, 4); (7, 3)]
let orgMap =
orgList
|> List.fold (fun acc item ->
let key = snd item
match Map.tryFind key acc with
| Some(value) ->
let map' = Map.remove key acc
Map.add(key) (item::value) map'
| None ->
Map.add(key) (item::[]) acc
) Map.empty<int, (int*int) list>
let findReports supervisor =
let rec findReports' acc collection =
match collection with
| head::tail ->
(findReports' (head::acc) tail)
@ match Map.tryFind (fst head) orgMap with
| Some(value) -> (findReports' [] value)
| None -> []
| [] -> acc
findReports' [] (Map.find supervisor orgMap)
findReports 2
|> List.map fst
|> List.distinct
rendimenti
val it : int list = [3; 4; 5; 7; 6]
findReports 2
restituisce
val it : (int * int) list = [(3, 2); (4, 2); (5, 3); (7, 3); (6, 4)]
ti rompo il basso per chiarire.
let orgList = [ (1, 2); (1, 3); (1, 4); (2, 5); (3, 6); (4, 5); (5, 6); (5, 7) ]
Prendiamo la vostra lista di tuple e creare una mappa funzionale di capo per (elenco (rapporto, capo)). Questo potrebbe essere conosciuto come un elenco di adiacenze, che viene utilizzato per i grafici di attraversamento.
let orgMap =
orgList
|> List.fold (fun acc item ->
let key = snd item
match Map.tryFind key acc with
Se è presente un elenco di rapporti sotto un capo, aggiungere a tale elenco.
| Some(reports) ->
let map' = Map.remove key acc
Map.add(key) (item::reports) map'
In caso contrario, aggiungere a una lista vuota e inserire nel dizionario.
| None ->
Map.add(key) (item::[]) acc
Iniziare con una mappa vuota come accumulatore.
) Map.empty<int, (int*int) list>
Recurse attraverso gli articoli per trovare tutti i report.
let findReports supervisor =
let rec findReports' acc collection =
match collection with
Se è presente un articolo, aggiungerlo all'accumulatore. Questo è BFS. Se si cambia l'espressione prima e dopo l'operatore concatenato (@), diventerà DFS.
Concatena l'elenco corrente all'elenco ricorsivo di rapporti ai rapporti.
@ match Map.tryFind (fst head) orgMap with
| Some(value) -> (findReports' [] value)
| None -> []
Se alla fine dell'elenco, restituire l'elenco.
| [] -> acc
Eseguire la funzione ricorsiva.
findReports' [] (Map.find supervisor orgMap)
Eseguire la funzione.
findReports 7
restituire solo i rapporti
|> List.map fst
non riportano il rapporto due volte.
|> List.distinct
Quando ho commentato di cambiare il titolo ho pensato che volevi fare una nuova domanda, dopo averci pensato, capisco cosa intendevi. Ho cambiato il titolo ma dal momento che è la tua domanda ovviamente dovresti cambiarlo in qualcos'altro se questo non ti soddisfa. –