From 8599df87bf4926ff91f4b9cc199d611889b51429 Mon Sep 17 00:00:00 2001 From: williamgilpin Date: Sun, 5 Nov 2023 12:22:40 -0600 Subject: [PATCH 1/3] add optional depth return on lookup --- src/suffix_tree/tree.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/suffix_tree/tree.py b/src/suffix_tree/tree.py index 87af9c9..69d13ac 100644 --- a/src/suffix_tree/tree.py +++ b/src/suffix_tree/tree.py @@ -124,7 +124,7 @@ def find_path(self, path: Path) -> Tuple[Node, int, Optional[Node]]: """ return self.root.find_path(path.S, path.start, path.end) - def find(self, S: Symbols) -> bool: + def find(self, S: Symbols, return_depth=False) -> bool: """Find a sequence in the tree. :param Sequence S: a sequence of symbols @@ -136,10 +136,14 @@ def find(self, S: Symbols) -> bool: True >>> tree.find("abc") False + >>> tree.find("abx", return_depth=True) + (True, 2) """ path = Path(S) dummy_node, matched_len, dummy_child = self.find_path(path) + if return_depth: + return matched_len == len(path), matched_len return matched_len == len(path) def find_all(self, S: Symbols) -> List[Tuple[Id, Path]]: From 40a672c3250cd1048f7266abb046580ccfeea7ac Mon Sep 17 00:00:00 2001 From: williamgilpin Date: Sun, 5 Nov 2023 13:13:37 -0600 Subject: [PATCH 2/3] update node depth tracing --- .DS_Store | Bin 0 -> 8196 bytes src/.DS_Store | Bin 0 -> 6148 bytes src/suffix_tree/node.py | 14 +++++++++++--- src/suffix_tree/tree.py | 21 +++++++++++++++++---- 4 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 .DS_Store create mode 100644 src/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2ea8a6f47de2e838b3d9ef1b05838951292b4166 GIT binary patch literal 8196 zcmeHMU2GIp6u#fIz>E{<6ez_7*(Fs(D6&xg8iZ`OtrZFs*e%`i(`9yNfCZtYU0FV@#%lOHHNjI*rfsu^BNTE3%T; znny=hwIy2Ep1Iq!b>FI*UAk|2d9A^t+_n^5XJ^^0 zQceR!*RBjZG}Bnr?P7(T%?{hnSPu&CV%fFrovvs3mg@}WeDk=^=lDXCrgD2dx9oQY zi{&g@UwF;t=jbc(U~i9E_DCwqyR(`XF1~Bo$~Enq()VxOG0~tk&Q{f?c>`6;vkJC3 zsCz}zF)ZhB|A=MyNA?n&j&B{Z%(9|1qBZO2!{)^7My+A~?Xg&{Qm~FyEdPYoBFkc} zSUjP~+UflUC9~Z%c%%``#A5L~WqBXBca}}+g;|X)y@vwytVgMZm$TwtMbW(MQM$Jx zR9)RBE1J=7>jl#eP3t$1sdu0%G7F7O_sL4G=nfClMSH>)OLfSyc6NxLc$@C|eI?Vm zd`YQpS>Ed%(aUDv2r;V`u|<}H+eLOB(rsA2TMn}BjmKhxe5nq@FpV(jSZvpBI>&js z>y}fsh|7evptRglV^d3NnHUBTwxp6mn_HU?C4Xhz!ICV^wz45sVkg*>>{<3Q`+%Kh zXV~ZLD|UhX$bMp%*stt2_B;C%^_YnUXlO(X3$PH2upDc!7VD5kFScPj`jEu|3?UC4 zhv1@wWAJbSkKj=}hR5*?p2PDvg;($v-o`t451---oW(gz;5&SeA8-kONcGY*X}Z)P zX;Py!M_MA?EhVLPX|vQLu3W0s&*0>Yq#Wtt!+`21{Fo=bdj0x|_dL+EWoz$ETR-2< z;uSMzZqvNx1TUivn>sG@P0+K($g7zikb6=|1mq5wFqN28R|^)Zi{kyne)IU$daTu{ zHiK8AJi)yet1WSD8r6qTm#9nQ+H|T7p)QZFh-(s+q)?Ob)v8uU1*ZhDYvU_a4YE+$ z)s3oFPo*c+&FUgmV~SAH@vgYW3rYT$DSeKeXWtN|e<4c$g*wP+MgmKaBm!?n3LWS| zH+Enrb|DiGIgf)Vpa>fdk@*c8;_f0(D|ApYQ*>Z~Xng<{rri zfe3+H5CPP8WxCRo*o_{Te6O9L;~*WpaldgPgAnQ_eFz}^@*jpYPLL~)NriG;NU~7- b&p!n4-<#3-v!Arl`(L1TOZ0yOXo*3W literal 0 HcmV?d00001 diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..cbc9853ec431a6211572428b5e69e8ae67f5ebff GIT binary patch literal 6148 zcmeHK&5zqe6n`(9cI{fFvt`Scui7Z0LS?I_EN!VOs%$n@=?8RacDq~pk=pUJwd&Zx z<0K2KMd3*KID$Y$9FP!jg>4I0E+BCMRTcEa9WML>h&MBi#A?YEA@GZ4e)GP@em~nY z834d)$KMOU0KlLovABu4zY*z|ZJiV{%LpN=IRaRM2BeSxUl*Mlat3k+{%s7%Z`T3= z9k@)tzka{m>xs4(#vVo7^4eh_(sKDO7DkF2HjWyjhGkr+UyXb9)J;30>L%x;HW$aC zHyFF#nSl2iYdP`P#OFigX2u!-g6y;J2$XX?Pp zq_cc*YTu-@|G?DBifL>s?KyP1aV=~`@f(^=q{T!yO{E&RQlvZYg~&ji8x7T)MSeR&99@j%4?iz%Vcqe zCxXy4f4*-E8{2yS__hZooX25BAJn@8Ngv;Dz`9)85yVb4 z$R33j4;NRF~MbA!Pl^luj6%m3*W|f@I8DVKfoLKA%23N;%E3d zeu1la6K~^J_%(im-{TK>Pv2i*@FJgFd*Apg=|f)RZas;@IJ!a+gY31*!?i5lu!e`^ zo}7W4f&VE3a(!^9Nvvep*Qk~b>eLZ{ut;VlG?r%xnd4+w$*`}HJS3=733aMmnYCS| zlikVmN``%nIvp@Od|-BE%uXn%(*Ye74p`Bc_c;SO18W(O|NTjr-2aaZKmV(syvrHL z8TfB9fW=z9R;Ajqy>(rca<6r$U7{vM#`QI-6za0=SPkS>yq%g7@;P!qSjn)jkt`(n P9|1)}-sKGZqYV5B4lV@2 literal 0 HcmV?d00001 diff --git a/src/suffix_tree/node.py b/src/suffix_tree/node.py index 5889b08..dc5497a 100644 --- a/src/suffix_tree/node.py +++ b/src/suffix_tree/node.py @@ -1,6 +1,6 @@ """Node classes for a Generalized Suffix Tree.""" -from typing import Optional, Tuple, List, Set, Dict +from typing import Optional, Tuple, List, Set, Dict, Union from .util import Path, Id, Symbol, Symbols, debug from . import lca_mixin, util @@ -204,8 +204,8 @@ def post_order(self, f) -> None: f(self) def find_path( - self, S: Symbols, start: int, end: int - ) -> Tuple["Node", int, Optional["Node"]]: + self, S: Symbols, start: int, end: int, return_nodedepth: bool = False + ) -> Union[Tuple["Node", int, Optional["Node"]], Tuple["Node", int, Optional["Node"], int]]: """Find a path starting from this node. The path is absolute. @@ -217,6 +217,7 @@ def find_path( node: Node = self matched_len = self.depth max_len = end - start + node_depth = 0 while matched_len < max_len: # find the edge to follow @@ -231,13 +232,20 @@ def find_path( matched_len += 1 if matched_len < child.depth: # the path ends between node and child + if return_nodedepth: + return node, matched_len, None, node_depth return node, matched_len, child # we reached another node, loop node = child + node_depth += 1 else: # no edge to follow + if return_nodedepth: + return node, matched_len, None, node_depth return node, matched_len, None # path exhausted + if return_nodedepth: + return node, matched_len, None, node_depth return node, matched_len, None def split_edge(self, new_len: int, child: Node) -> "Internal": diff --git a/src/suffix_tree/tree.py b/src/suffix_tree/tree.py index 69d13ac..99bfe51 100644 --- a/src/suffix_tree/tree.py +++ b/src/suffix_tree/tree.py @@ -116,15 +116,23 @@ def add( assert isinstance(builder, Builder) builder.build(self.root, id_, itertools.chain(S, [UniqueEndChar(id_)])) - def find_path(self, path: Path) -> Tuple[Node, int, Optional[Node]]: + def find_path( + self, path: Path, return_nodedepth: bool = False, + ) -> Union[Tuple[Node, int, Optional[Node]], Tuple[Node, int, Optional[Node], int]]: """Find a path in the tree. See: :py:func:`suffix_tree.node.Internal.find_path` """ + if return_nodedepth: + return self.root.find_path( + path.S, path.start, path.end, return_nodedepth=True + ) return self.root.find_path(path.S, path.start, path.end) - def find(self, S: Symbols, return_depth=False) -> bool: + def find( + self, S: Symbols, return_nodedepth: bool = False + ) -> Union[bool, Tuple[bool, int]]: """Find a sequence in the tree. :param Sequence S: a sequence of symbols @@ -141,9 +149,14 @@ def find(self, S: Symbols, return_depth=False) -> bool: """ path = Path(S) + + if return_nodedepth: + dummy_node, matched_len, dummy_child, nodedepth = self.find_path( + path, return_nodedepth=return_nodedepth + ) + return matched_len == len(path), nodedepth + dummy_node, matched_len, dummy_child = self.find_path(path) - if return_depth: - return matched_len == len(path), matched_len return matched_len == len(path) def find_all(self, S: Symbols) -> List[Tuple[Id, Path]]: From c20933110973394c4670055b8f94bc3ed6b1db54 Mon Sep 17 00:00:00 2001 From: williamgilpin Date: Sun, 5 Nov 2023 13:14:07 -0600 Subject: [PATCH 3/3] remove ds file --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 2ea8a6f47de2e838b3d9ef1b05838951292b4166..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMU2GIp6u#fIz>E{<6ez_7*(Fs(D6&xg8iZ`OtrZFs*e%`i(`9yNfCZtYU0FV@#%lOHHNjI*rfsu^BNTE3%T; znny=hwIy2Ep1Iq!b>FI*UAk|2d9A^t+_n^5XJ^^0 zQceR!*RBjZG}Bnr?P7(T%?{hnSPu&CV%fFrovvs3mg@}WeDk=^=lDXCrgD2dx9oQY zi{&g@UwF;t=jbc(U~i9E_DCwqyR(`XF1~Bo$~Enq()VxOG0~tk&Q{f?c>`6;vkJC3 zsCz}zF)ZhB|A=MyNA?n&j&B{Z%(9|1qBZO2!{)^7My+A~?Xg&{Qm~FyEdPYoBFkc} zSUjP~+UflUC9~Z%c%%``#A5L~WqBXBca}}+g;|X)y@vwytVgMZm$TwtMbW(MQM$Jx zR9)RBE1J=7>jl#eP3t$1sdu0%G7F7O_sL4G=nfClMSH>)OLfSyc6NxLc$@C|eI?Vm zd`YQpS>Ed%(aUDv2r;V`u|<}H+eLOB(rsA2TMn}BjmKhxe5nq@FpV(jSZvpBI>&js z>y}fsh|7evptRglV^d3NnHUBTwxp6mn_HU?C4Xhz!ICV^wz45sVkg*>>{<3Q`+%Kh zXV~ZLD|UhX$bMp%*stt2_B;C%^_YnUXlO(X3$PH2upDc!7VD5kFScPj`jEu|3?UC4 zhv1@wWAJbSkKj=}hR5*?p2PDvg;($v-o`t451---oW(gz;5&SeA8-kONcGY*X}Z)P zX;Py!M_MA?EhVLPX|vQLu3W0s&*0>Yq#Wtt!+`21{Fo=bdj0x|_dL+EWoz$ETR-2< z;uSMzZqvNx1TUivn>sG@P0+K($g7zikb6=|1mq5wFqN28R|^)Zi{kyne)IU$daTu{ zHiK8AJi)yet1WSD8r6qTm#9nQ+H|T7p)QZFh-(s+q)?Ob)v8uU1*ZhDYvU_a4YE+$ z)s3oFPo*c+&FUgmV~SAH@vgYW3rYT$DSeKeXWtN|e<4c$g*wP+MgmKaBm!?n3LWS| zH+Enrb|DiGIgf)Vpa>fdk@*c8;_f0(D|ApYQ*>Z~Xng<{rri zfe3+H5CPP8WxCRo*o_{Te6O9L;~*WpaldgPgAnQ_eFz}^@*jpYPLL~)NriG;NU~7- b&p!n4-<#3-v!Arl`(L1TOZ0yOXo*3W