Мне нравятся головоломки f #, поэтому я сделал удар в этом месте. Надеюсь, вам понравится.
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
возвращает
val it : int list = [3; 4; 5; 7; 6]
findReports 2
возвращает
val it : (int * int) list = [(3, 2); (4, 2); (5, 3); (7, 3); (6, 4)]
я сломаю его вниз, чтобы уточнить.
let orgList = [ (1, 2); (1, 3); (1, 4); (2, 5); (3, 6); (4, 5); (5, 6); (5, 7) ]
Мы список кортежей и создать функциональную карту босса (список (отчет, босс)). Это может быть известно как список смежности, который используется для перемещения графиков.
let orgMap =
orgList
|> List.fold (fun acc item ->
let key = snd item
match Map.tryFind key acc with
Если есть список отчетов под боссом, добавьте в этот список.
| Some(reports) ->
let map' = Map.remove key acc
Map.add(key) (item::reports) map'
В противном случае добавьте в пустой список и вставьте в словарь.
| None ->
Map.add(key) (item::[]) acc
Начните с пустой карты как аккумулятора.
) Map.empty<int, (int*int) list>
Считать предметы, чтобы найти все отчеты.
let findReports supervisor =
let rec findReports' acc collection =
match collection with
Если есть предмет, добавьте его в аккумулятор. Это BFS. Если вы переключите выражение до и после оператора конкатенации (@), оно станет DFS.
| 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 7
Возврат только отчеты
|> List.map fst
Не передавать отчет дважды.
|> List.distinct
Когда я прокомментировал изменение названия, я думал, что вы хотите задать новый вопрос, подумав об этом, я понимаю, что вы имели в виду. Я изменил название, но, так как это ваш вопрос, очевидно, вы должны изменить его на что-то еще, если это вас не устраивает. –