删除列表中两次出现之间的元素
Delete elements between two occurrences in list
我必须创建一个函数,它接受一个列表 return 列表,但没有出现之间的元素。
例如:[1; 2; 3; 4; 2; 7; 14; 21; 7; 5] -> [1; 2; 7; 5]
我想做这个我会拿榜首,然后看看
如果尾部还有另一个事件,那么我浏览列表,当我找到事件时,我删除它们之间的所有内容,只保留其中一个。
首先我尝试了这样的事情:
let rec remove list = match list with
| [] -> []
| h::t -> if(List.mem h t) then
(*Here I would like to go through the list element by element to
find the occurence and then delete everything between*)
else
remove t
因此,对于我没有成功完成的部分,我制作了一个允许在两个给定点之间分割列表的函数,就像这样:
let slice list i k =
let rec take n = function
| [] -> []
| h :: t -> if n = 0 then [] else h :: take (n-1) t
in
let rec drop n = function
| [] -> []
| h :: t as l -> if n = 0 then l else drop (n-1) t
in
take (k - i + 1) (drop i list);;
(*Use: slice ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 2 3;;*)
我也有这个功能可以让我得到列表中的点索引:
let index_of e l =
let rec index_rec i = function
| [] -> raise Not_found
| hd::tl -> if hd = e then i else index_rec (i+1) tl
in
index_rec 0 l ;;
(*Use: index_of 5 [1;2;3;4;5;6] -> return 4*)
但我真的不知道如何将它们组合起来以获得我期望的结果。
这是我做的:
let rec remove liste =
let rec aux l el = match l with
| [] -> raise Not_found
| x :: xs -> if el = x then try aux xs el with Not_found -> xs
else aux xs el in
match liste with
| [] -> []
| x :: xs -> try let r = x :: aux xs x in remove r with Not_found -> x :: remove xs;;
我的辅助功能return l 中最后一次出现 el 之后的列表。如果您有任何问题或需要更多解释,请在评论中问我
一个版本使用 option
类型来判断某个元素是否出现在列表的后面:
let rec find_tail ?(eq = (=)) lst elem =
match lst with
| x :: _ when eq x elem -> Some lst
| _ :: xs -> find_tail ~eq xs elem
| [] -> None
let rec remove ?(eq = (=)) lst =
match lst with
| [x] -> [x]
| x :: xs -> begin
match find_tail ~eq xs x with
| Some tail -> x :: remove ~eq (List.tl tail)
| None -> x :: remove ~eq xs
end
| [] -> []
还允许您指定比较函数(默认为 =
)。
我必须创建一个函数,它接受一个列表 return 列表,但没有出现之间的元素。
例如:[1; 2; 3; 4; 2; 7; 14; 21; 7; 5] -> [1; 2; 7; 5]
我想做这个我会拿榜首,然后看看 如果尾部还有另一个事件,那么我浏览列表,当我找到事件时,我删除它们之间的所有内容,只保留其中一个。
首先我尝试了这样的事情:
let rec remove list = match list with
| [] -> []
| h::t -> if(List.mem h t) then
(*Here I would like to go through the list element by element to
find the occurence and then delete everything between*)
else
remove t
因此,对于我没有成功完成的部分,我制作了一个允许在两个给定点之间分割列表的函数,就像这样:
let slice list i k =
let rec take n = function
| [] -> []
| h :: t -> if n = 0 then [] else h :: take (n-1) t
in
let rec drop n = function
| [] -> []
| h :: t as l -> if n = 0 then l else drop (n-1) t
in
take (k - i + 1) (drop i list);;
(*Use: slice ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 2 3;;*)
我也有这个功能可以让我得到列表中的点索引:
let index_of e l =
let rec index_rec i = function
| [] -> raise Not_found
| hd::tl -> if hd = e then i else index_rec (i+1) tl
in
index_rec 0 l ;;
(*Use: index_of 5 [1;2;3;4;5;6] -> return 4*)
但我真的不知道如何将它们组合起来以获得我期望的结果。
这是我做的:
let rec remove liste =
let rec aux l el = match l with
| [] -> raise Not_found
| x :: xs -> if el = x then try aux xs el with Not_found -> xs
else aux xs el in
match liste with
| [] -> []
| x :: xs -> try let r = x :: aux xs x in remove r with Not_found -> x :: remove xs;;
我的辅助功能return l 中最后一次出现 el 之后的列表。如果您有任何问题或需要更多解释,请在评论中问我
一个版本使用 option
类型来判断某个元素是否出现在列表的后面:
let rec find_tail ?(eq = (=)) lst elem =
match lst with
| x :: _ when eq x elem -> Some lst
| _ :: xs -> find_tail ~eq xs elem
| [] -> None
let rec remove ?(eq = (=)) lst =
match lst with
| [x] -> [x]
| x :: xs -> begin
match find_tail ~eq xs x with
| Some tail -> x :: remove ~eq (List.tl tail)
| None -> x :: remove ~eq xs
end
| [] -> []
还允许您指定比较函数(默认为 =
)。