Advertisement
vkazar

Untitled

Jan 15th, 2024
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.58 KB | None | 0 0
  1. package sprint8.fin.B
  2.  
  3. fun main() {
  4.     val a = Trie("abaab")
  5. }
  6.  
  7. class Trie(inputString: String) {
  8.     private val terminator = '$'
  9.     val string = "$inputString$terminator"
  10.     val root: Node = Node().apply { addVertex(Vertex(string.lastIndex, string.length)) }
  11.  
  12.     inner class Node(inputVertex: Vertex?) {
  13.         constructor() : this(null)
  14.  
  15.         val stringUntil = inputVertex?.right ?: 0
  16.  
  17.         private val vertices = mutableMapOf<Char, Vertex>()
  18.  
  19.         fun addVertex(vertex: Vertex) {
  20.             vertices[vertex.startChar] = vertex
  21.         }
  22.  
  23.         fun hasVertex(char: Char) = vertices.containsKey(char)
  24.  
  25.         fun getVertex(char: Char) = vertices[char]
  26.  
  27.         operator fun get(char: Char) = vertices[char]
  28.  
  29.         val sufLink: Position
  30.             get() {
  31.                 var cur = root
  32.                 var curPos = 1
  33.                 while (curPos < stringUntil) {
  34.                     val vertex = cur.vertices[string[curPos]]!!
  35.                     cur = vertex.to
  36.                     curPos += vertex.len
  37.                 }
  38.                 return cur.position
  39.             }
  40.  
  41.         val position = Position(this)
  42.  
  43.         override fun toString(): String = string.substring(0, stringUntil)
  44.     }
  45.  
  46.     inner class Vertex(val left: Int, right: Int) {
  47.         constructor(left: Int) : this(left, string.length)
  48.  
  49.         var right = right
  50.             private set
  51.         var to = Node(this)
  52.         val startChar = string[left]
  53.  
  54.         val len
  55.             get() = right - left
  56.  
  57.         fun split(pos: Int): Node {
  58.             val splitOffVertex = Vertex(left + pos, right).also { it.to = this.to }
  59.             right = splitOffVertex.left
  60.  
  61.             return Node(this)
  62.                 .also {
  63.                     to = it
  64.                     it.addVertex(splitOffVertex)
  65.                 }
  66.         }
  67.  
  68.         override fun toString(): String {
  69.             return string.substring(left, right)
  70.         }
  71.     }
  72.  
  73.     inner class Position(val node: Node, val char: Char?, val pos: Int) {
  74.         constructor(node: Node) : this(node, null, 0)
  75.  
  76.         val isNode get() = pos == 0
  77.  
  78.         val link: Position
  79.             get() {
  80.                 if (char == null || pos == 0) return node.sufLink
  81.                 var node = node.sufLink.node
  82.                 var pos = this.pos
  83.                 var char = this.char
  84.                 var vertex = node[char]!!
  85.                 while (pos > vertex.len) {
  86.                     node = vertex.to
  87.                     pos -= vertex.len
  88.                     char = string[node.stringUntil]
  89.                     vertex = node[char]!!
  90.                 }
  91.                 return Position(node, char, pos)
  92.             }
  93.  
  94.         override fun toString(): String = "${node}${string.substring(node.stringUntil, pos)}"
  95.     }
  96.  
  97.     init {
  98.         var curr = root.position
  99.         fun add(addPos: Int) {
  100.             val char = string[addPos]
  101.             while (curr.node != root && !curr.node.hasVertex(char)) {
  102.                 if (!curr.isNode) {
  103.                     curr.node.getVertex(char)
  104.                         ?.split(curr.pos)
  105.                         ?.addVertex(Vertex(addPos, string.length))
  106.                     curr = curr.link
  107.                 }
  108.             }
  109.             if (curr.isNode && curr.node.hasVertex(char) || string[curr.node.stringUntil + curr.pos] == char) {
  110.                 curr = Position(curr.node, curr.char, curr.pos + 1)
  111.             } else {
  112.                 curr.node.addVertex(Vertex(addPos))
  113.             }
  114.         }
  115.  
  116.         for (i in string.indices) {
  117.             add(i)
  118.         }
  119.     }
  120. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement