2017-02-09 29 views
1

Я новичок в Ocaml с любопытством, как написать функцию под названием Seperate_by, которая принимает два параметра, список и список элементов, где для разделения исходного списка.Разделить список в список списков со списком как параметр для разбиения Ocaml

Например,

Seperate_by [1;2;3;4;5;6;7] [3;5] 

Должен иметь выход [[1;2];[4];[6;7]]

Спасибо заранее!

+0

Вы были близки! Но это ключ тильды (squiggly key) для форматирования встроенного кода только fyi. –

+0

Как и в стороне, имена функций не могут быть капитализированы в OCaml :) –

+2

Что вы пробовали, и какова, по-видимому, проблема с ним? –

ответ

0

Вы можете попробовать это:

let seperate_by l lsep = 
    let add acc res = if acc<>[] then acc::res else res in 
    let(res,acc)= 
    List.fold_right (fun x (res,acc) -> 
     if List.exists ((=)x) lsep then (add acc res,[]) else (res,x::acc) 
    ) l ([],[]) 
    in 
    add acc res 

Тест:

# seperate_by [1;2;3;4;5;6;7] [3;5];; 
- : int list list = [[1; 2]; [4]; [6; 7]] 
# seperate_by [1;2;3;4;5;6;7] [3;5;7];; 
- : int list list = [[1; 2]; [4]; [6]] 
# seperate_by [1;2;3;4;5;6;7] [1;5;7];; 
- : int list list = [[2; 3; 4]; [6]] 
0
let rec seperate_by l sign= 

    let rec aux2 = function 
    (head,[])->(head,[]) 
    |(head,x::r) -> if List.exists ((=) x) sign then (head,r) 
    else aux2 ([email protected][x],r) 
    in 

    let res = aux2 ([],l) in 
    match res with 
    |(head,[])->head::[] 
    |(sub_list,rest_list) -> (sub_list)::(split rest_list sign) 
     ;; 

(* функция aux2 возвращает первый sub_list из списка, так что я продолжать строить список с остальной частью списка и окончательно мы имеем результат *)

Примечание: Я видел, что ваш имя функции начинается bt в верхнем регистре. Вся переменная начинается с буквы верхнего регистра, означает «тип» в Ocaml, поэтому имя функции должно начинаться с строчной буквы, возможно, это ваша проблема?

+0

Удивительный! Вы знаете, есть ли способ сделать это, используя List.fold_left вместо рекурсии? –

+0

@V. Встреча Мишеля лучше, чем моя. Фактически, вы можете использовать List.fold_left, используя '@' или использовать List.fold_right, используя '::', как это сделал Мишель в 'else (res, x :: acc)' u может использовать List.fold_left, изменив его на 'else (res, acc @ [x])' corse, вы должны изменить порядок параметров в fold_left. –

0
let rec seperate_by l sign= 
    let rec aux2 = function 
     (head,[])->(head,[]) 
     |(head,x::y::r) when x=y -> if List.exists ((=) x) sign then ([email protected][],y::r) else aux2 ([email protected][x],y::r) 
     |(head,x::r) -> if List.exists ((=) x) sign then (head,r) else aux2 ([email protected][x],r) 
    in 
    let res = aux2 ([],l) 
    in 
    match res with 
     |(head,[])->head::[] 
     |(sub_list,rest_list) -> (sub_list)::(seperate_by rest_list sign)  
+0

Я добавил новый case.Zhenyu ответ более ясен, но я хочу знать, как вы конвертируете его в формат сгиба –