列表列表列表,其中列表是一个参数,用于拆分ocaml

问题描述 投票:0回答:4
,例如,

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

输出的输出应为

[[1;2];[4];[6;7]]

	
您可以尝试以下方法:

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

测试:
list split ocaml nested-lists
4个回答
0
投票
# 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]]

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 (head@[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 a fippercase。所有变量以大写字母开头意味着OCAML中的“类型”,因此函数的名称应该以小写字母开始,可能是您的问题?

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 (head@[],y::r) else  aux2 (head@[x],y::r)
      |(head,x::r) -> if List.exists ((=) x) sign then (head,r) else  aux2 (head@[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
投票
.
。
llet将单个令牌分开。这是一个更简单的问题。
let rec split_on tok lst = let rec aux lst acc = match lst, acc with | [], [] -> [] | [], _ -> [acc] | x::xs, [] when x = tok -> aux xs [] | x::xs, y::ys when x = tok -> acc :: aux xs [] | x::xs, _ -> aux xs (x::acc) in aux lst [] |> List.(map rev)

0
投票
# split_on 3 [1; 2; 3; 4; 5; 6; 72; 3; 43; 3; 5; 3];; - : int list list = [[1; 2]; [4; 5; 6; 72]; [43]; [5]]

现在,如果我们也想在6

...

# split_on 3 [1; 2; 3; 4; 5; 6; 72; 3; 43; 3; 5; 3] |> List.concat_map (split_on 6);; - : int list list = [[1; 2]; [4; 5]; [72]; [43]; [5]]
因此,我们只需要在第一个令牌上拆分,然后使用
List.concat_map
对每个后续令牌进行拆分。这可以通过

List.fold_left

let rec separate_by lst = function | [] -> [lst] | t::ts -> List.( let first_split = split_on t lst in fold_left (fun i x -> concat_map (split_on x) i) first_split ts )

# separate_by [1; 2; 3; 4; 5; 6; 72; 3; 43; 3; 5; 3] [3; 5; 6];;
- : int list list = [[1; 2]; [4]; [72]; [43]]


© www.soinside.com 2019 - 2024. All rights reserved.