В настоящее время я изучаю OCaml и не могу составить подсписок, хотя могу составить список без пробелов как ['1'; '2'; '3'; '4'; '5'; '6']. Я не смог найти источники по моему вопросу, поэтому спасибо за объяснение, пожалуйста.
type chiffre = int (*0-9*);;
type chiffreCar = char (* '0' - '9'*)
type nombre = chiffre list;;
type txtnb = chiffreCar list ;;
let rec les_nb (a:txtnb) : txtnb =
match a with
| [] -> []
| ' ' :: tl -> les_nb(tl)
| hd::tl ->hd :: les_nb(tl) ;;
Мы можем использовать левую складку для перебора списка и его группировки, давая нам возможность использовать аккумулятор для легкого отслеживания последнего элемента, добавленного в выходной список.
Это приведет к построению списка результатов в обратном порядке, и мы получим несколько пустых списков с повторяющимися пробелами, но мы можем легко перевернуть их и отфильтровать пустые списки.
# let lst = ['1'; '2'; '3'; ' '; ' '; '4'; '5'; ' '; '6'];;
val lst : char list = ['1'; '2'; '3'; ' '; ' '; '4'; '5'; ' '; '6']
# let group lst =
lst
|> List.fold_left
(fun i x ->
match i, x with
| [], ' ' -> i
| _, ' ' -> [] :: i
| [], _ -> [[x]]
| y::ys, _ -> (x :: y) :: ys)
[]
|> List.filter @@ (<>) []
|> List.rev
|> List.map List.rev;;
val group : char list -> char list list = <fun>
# group lst;;
- : char list list = [['1'; '2'; '3']; ['4'; '5']; ['6']]
Альтернативно:
|> List.rev
|> List.map List.rev;;
Мы можем использовать List.rev_map.
|> List.rev_map List.rev;;
Разбивка звонка:
List.fold_left f [] ['1'; '2'; '3'; ' '; ' '; '4'; '5'; ' '; '6']
List.fold_left f [['1']] ['2'; '3'; ' '; ' '; '4'; '5'; ' '; '6']
List.fold_left f [['2'; '1']] ['3'; ' '; ' '; '4'; '5'; ' '; '6']
List.fold_left f [['3'; '2'; '1']] [' '; ' '; '4'; '5'; ' '; '6']
List.fold_left f [[]; ['3'; '2'; '1']] [' '; '4'; '5'; ' '; '6']
List.fold_left f [[]; []; ['3'; '2'; '1']] ['4'; '5'; ' '; '6']
List.fold_left f [['4']; []; ['3'; '2'; '1']] ['5'; ' '; '6']
List.fold_left f [['5'; '4']; []; ['3'; '2'; '1']] [' '; '6']
List.fold_left f [[]; ['5'; '4']; []; ['3'; '2'; '1']] ['6']
List.fold_left f [['6']; ['5'; '4']; []; ['3'; '2'; '1']] []
(List.filter @@ (<>) []) [['6']; ['5'; '4']; []; ['3'; '2'; '1']]
List.rev [['6']; ['5'; '4']; ['3'; '2'; '1']]
List.map List.rev [['3'; '2'; '1']; ['5'; '4']; ['6']]
[['1'; '2'; '3']; ['4'; '5']; ['6']]
Если вы хотите выразить это без использования List.fold_left
, вы можете использовать явный аккумулятор. Сопоставление с образцом отображается таким же образом.
# let rec group ?(acc=[]) lst =
match acc, lst with
| _, [] -> List.(rev @@ map rev @@ filter ((<>) []) acc)
| _, ' '::xs -> group ~acc: ([] :: acc) xs
| [], x::xs -> group ~acc: [[x]] xs
| y::ys, x::xs -> group ~acc: ((x :: y) :: ys) xs;;
val group : ?acc:char list list -> char list -> char list list = <fun>
# group lst;;
- : char list list = [['1'; '2'; '3']; ['4'; '5']; ['6']]