add delete function to rope.sml

This commit is contained in:
2024-02-15 14:05:50 +00:00
parent d5ffb4f762
commit ebf449205c
2 changed files with 158 additions and 79 deletions

View File

@@ -4,6 +4,7 @@ signature ROPE = sig
val of_string : string -> t val of_string : string -> t
val size : t -> int val size : t -> int
val insert : int * string * t -> t val insert : int * string * t -> t
val delete : int * int * t -> t
end end
structure Rope :> ROPE = struct structure Rope :> ROPE = struct
@@ -28,7 +29,6 @@ structure Rope :> ROPE = struct
exception AuxConstructor exception AuxConstructor
local
fun help_size(acc, rope) = fun help_size(acc, rope) =
case rope of case rope of
N0 s => N0 s =>
@@ -38,9 +38,8 @@ structure Rope :> ROPE = struct
| N2(_, lm, r) => | N2(_, lm, r) =>
help_size(acc + lm, r) help_size(acc + lm, r)
| _ => raise AuxConstructor | _ => raise AuxConstructor
in
fun size rope = help_size(0, rope) fun size rope = help_size(0, rope)
end
fun ins_root rope = fun ins_root rope =
case rope of case rope of
@@ -177,7 +176,6 @@ structure Rope :> ROPE = struct
| (l, r) => | (l, r) =>
N2(l, size l, r) N2(l, size l, r)
local
fun ins_leaf(cur_index, new_str, rope, old_str) = fun ins_leaf(cur_index, new_str, rope, old_str) =
if cur_index <= 0 then if cur_index <= 0 then
if is_less_than_target(old_str, new_str) then if is_less_than_target(old_str, new_str) then
@@ -205,6 +203,7 @@ structure Rope :> ROPE = struct
else else
(N3(N0 sub1, N0 new_str, N0 sub2), AddedNode) (N3(N0 sub1, N0 new_str, N0 sub2), AddedNode)
end end
fun ins(cur_index, new_str, rope) = fun ins(cur_index, new_str, rope) =
case rope of case rope of
N2(l, lm, r) => N2(l, lm, r) =>
@@ -260,7 +259,7 @@ structure Rope :> ROPE = struct
ins_leaf(cur_index, new_str, rope, old_str) ins_leaf(cur_index, new_str, rope, old_str)
| _ => | _ =>
raise AuxConstructor raise AuxConstructor
in
fun insert (index, str, rope) = fun insert (index, str, rope) =
let let
val (rope, action) = ins(index, str, rope) val (rope, action) = ins(index, str, rope)
@@ -273,5 +272,85 @@ structure Rope :> ROPE = struct
| DeletedNode => | DeletedNode =>
del_root rope) del_root rope)
end end
fun del_leaf(start_idx, end_idx, str) =
if start_idx <= 0 andalso end_idx >= String.size str then
(empty, false)
else if start_idx >= 0 andalso end_idx <= String.size str then
let
val sub1 = String.substring(str, 0, start_idx)
val sub2 = String.substring(str, end_idx, (String.size str - end_idx))
in
if start_idx + (String.size str - end_idx) <= target_length then
(N0 (sub1 ^ sub2), false)
else
(L2(sub1, sub2), true)
end
else if start_idx >= 0 andalso end_idx >= String.size str then
let
val str = String.substring(str, 0, start_idx)
in
(N0 str, false)
end
else
let
val str = String.substring(str, end_idx, String.size str - end_idx)
in
(N0 str, false)
end
fun del (start_idx, end_idx, rope) =
case rope of
N2(l, lm, r) =>
if lm > start_idx andalso lm > end_idx then
let
val (l, did_add) = del(start_idx, end_idx, l)
in
if did_add then
(ins_n2_left(l, r), did_add)
else
(N2(l, size l, r), did_add)
end
else if lm < start_idx andalso lm < end_idx then
let
val (r, did_add) = del(start_idx - lm, end_idx - lm, r)
in
if did_add then
(ins_n2_right(l, r), did_add)
else
(N2(l, lm, r), did_add)
end
else
let
val (l, did_add_l) = del(start_idx, end_idx, l)
val (r, did_add_r) = del(start_idx - lm, end_idx - lm, r)
in
if did_add_l then
(ins_n2_left(l, r), did_add_l)
else if did_add_r then
(ins_n2_right(l, r), did_add_r)
else
(N2(l, size l, r), false)
end
| N1 t =>
let
val (t, did_add) = del(start_idx, end_idx, t)
in
if did_add then
(ins_n1 t, did_add)
else
(N1 t, did_add)
end
| N0 str =>
del_leaf(start_idx, end_idx, str)
fun delete(start, length, rope) =
let
val (rope, did_add) = del(start, start + length, rope)
in
if did_add then
ins_root rope
else
del_root rope
end end
end end

View File

@@ -21,12 +21,12 @@ fun run_txns arr =
let let
val rope = val rope =
if del_num > 0 if del_num > 0
then delete pos del_num rope then Rope.delete(pos, del_num, rope)
else rope else rope
val str_size = String.size ins_str val str_size = String.size ins_str
val rope = val rope =
if str_size > 0 if str_size > 0
then insert pos ins_str rope then Rope.insert(pos, ins_str, rope)
else rope else rope
in in
rope rope