classNode:def__init__(self):self.children={}self.suffix_link=Noneself.start=-1self.end=-1self.suffix_index=-1classSuffixTree:def__init__(self,text):self.text=textself.root=Node()self.active_node=self.rootself.active_edge=-1self.active_length=0self.remaining_suffixes=0self.leaf_end=-1self.node_count=0self.build_tree()defbuild_tree(self):foriinrange(len(self.text)):self.extend(i)defextend(self,pos):self.leaf_end=posself.remaining_suffixes+=1last_new_node=Nonewhileself.remaining_suffixes>0:ifself.active_length==0:self.active_edge=posifself.active_edgenotinself.active_node.children:self.active_node.children[self.active_edge]=Node()self.active_node.children[self.active_edge].start=posself.active_node.children[self.active_edge].end=self.leaf_endself.active_node.children[self.active_edge].suffix_index=pos-self.remaining_suffixes+1self.node_count+=1iflast_new_nodeisnotNone:last_new_node.suffix_link=self.active_nodelast_new_node=Noneself.remaining_suffixes-=1else:next_node=self.active_node.children[self.active_edge]ifself.walk_down(next_node):continueifself.text[next_node.start+self.active_length]==self.text[pos]:self.active_length+=1iflast_new_nodeisnotNone:last_new_node.suffix_link=self.active_nodebreaksplit_node=Node()split_node.start=next_node.startsplit_node.end=next_node.start+self.active_length-1self.active_node.children[self.active_edge]=split_nodesplit_node.children[self.text[pos]]=Node()split_node.children[self.text[pos]].start=possplit_node.children[self.text[pos]].end=self.leaf_endsplit_node.children[self.text[pos]].suffix_index=pos-self.remaining_suffixes+1next_node.start+=self.active_lengthsplit_node.children[self.text[next_node.start]]=next_nodeself.node_count+=2iflast_new_nodeisnotNone:last_new_node.suffix_link=split_nodelast_new_node=split_nodeself.remaining_suffixes-=1ifself.active_node==self.rootandself.active_length>0:self.active_length-=1self.active_edge=pos-self.remaining_suffixes+1elifself.active_node!=self.root:self.active_node=self.active_node.suffix_linkdefwalk_down(self,node):ifself.active_length>=node.end-node.start+1:self.active_edge+=node.end-node.start+1self.active_length-=node.end-node.start+1self.active_node=nodereturnTruereturnFalse# 사용 예text="banana$"suffix_tree=SuffixTree(text)