Advertisement
Guest User

Untitled

a guest
Jan 15th, 2025
19
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.05 KB | None | 0 0
  1. -- Локальные переменные для оптимизации
  2. local pairs = pairs
  3. local table_insert = table.insert
  4. local string_utf8sub = string.utf8sub
  5. local string_utf8len = string.utf8len
  6.  
  7. -- Локальная таблица для хранения методов RadixTree
  8. local RadixTreeMethods = {}
  9.  
  10. -- Функция для добавления строки
  11. function RadixTreeMethods:insert(word, value)
  12.     local node = self.table
  13.     local i = 1
  14.     local wordLength = string_utf8len(word)
  15.  
  16.     while i <= wordLength do
  17.         node.c = node.c or {}
  18.         local found = false
  19.  
  20.         -- Поиск совпадающего префикса среди дочерних узлов
  21.         for childPrefix, childNode in pairs(node.c) do
  22.             local commonPrefix = ""
  23.             local minLength = math.min(string_utf8len(childPrefix), wordLength - i + 1)
  24.             for j = 1, minLength do
  25.                 if string_utf8sub(childPrefix, j, j) == string_utf8sub(word, i + j - 1, i + j - 1) then
  26.                     commonPrefix = commonPrefix .. string_utf8sub(childPrefix, j, j)
  27.                 else
  28.                     break
  29.                 end
  30.             end
  31.  
  32.             if string_utf8len(commonPrefix) > 0 then
  33.                 -- Если найден общий префикс, разделяем узел
  34.                 if commonPrefix ~= childPrefix then
  35.                     local newChild = { c = {} }
  36.                     newChild.c[string_utf8sub(childPrefix, string_utf8len(commonPrefix) + 1)] = childNode
  37.                     node.c[commonPrefix] = newChild
  38.                     node.c[childPrefix] = nil
  39.                 end
  40.  
  41.                 -- Переходим к следующему узлу
  42.                 node = node.c[commonPrefix]
  43.                 i = i + string_utf8len(commonPrefix)
  44.                 found = true
  45.                 break
  46.             end
  47.         end
  48.  
  49.         -- Если совпадающий префикс не найден, создаем новый узел
  50.         if not found then
  51.             local remainingWord = string_utf8sub(word, i)
  52.             node.c[remainingWord] = {
  53.                 value = (i + string_utf8len(remainingWord) > wordLength) and value or nil,
  54.                 c = (i + string_utf8len(remainingWord) <= wordLength) and {} or nil
  55.             }
  56.             break
  57.         end
  58.     end
  59. end
  60.  
  61. -- Функция для поиска строки
  62. function RadixTreeMethods:search(word)
  63.     local node = self.table
  64.     local i = 1
  65.     local wordLength = string_utf8len(word)
  66.  
  67.     while i <= wordLength do
  68.         local found = false
  69.  
  70.         for childPrefix, childNode in pairs(node.c or {}) do
  71.             if string_utf8sub(childPrefix, 1, 1) == string_utf8sub(word, i, i) then
  72.                 local prefixLength = string_utf8len(childPrefix)
  73.                 if string_utf8sub(word, i, i + prefixLength - 1) == childPrefix then
  74.                     node = childNode
  75.                     i = i + prefixLength
  76.                     found = true
  77.                     break
  78.                 end
  79.             end
  80.         end
  81.  
  82.         if not found then
  83.             return nil
  84.         end
  85.     end
  86.  
  87.     return node.value
  88. end
  89.  
  90. -- Функция для поиска по префиксу (автодополнение)
  91. function RadixTreeMethods:searchPrefix(prefix)
  92.     local node = self.table
  93.     local i = 1
  94.     local prefixLength = string_utf8len(prefix)
  95.  
  96.     while i <= prefixLength do
  97.         local found = false
  98.  
  99.         for childPrefix, childNode in pairs(node.c or {}) do
  100.             if string_utf8sub(childPrefix, 1, 1) == string_utf8sub(prefix, i, i) then
  101.                 local childPrefixLength = string_utf8len(childPrefix)
  102.                 if string_utf8sub(prefix, i, i + childPrefixLength - 1) == childPrefix then
  103.                     node = childNode
  104.                     i = i + childPrefixLength
  105.                     found = true
  106.                     break
  107.                 end
  108.             end
  109.         end
  110.  
  111.         if not found then
  112.             return {}
  113.         end
  114.     end
  115.  
  116.     -- Сбор всех слов с данным префиксом
  117.     local results = {}
  118.     local stack = { { node = node, prefix = prefix } }
  119.  
  120.     while #stack > 0 do
  121.         local current = table.remove(stack)
  122.         local currentNode = current.node
  123.         local currentPrefix = current.prefix
  124.  
  125.         if currentNode.value ~= nil then
  126.             table_insert(results, { word = currentPrefix, value = currentNode.value })
  127.         end
  128.  
  129.         for childPrefix, childNode in pairs(currentNode.c or {}) do
  130.             table_insert(stack, { node = childNode, prefix = currentPrefix .. childPrefix })
  131.         end
  132.     end
  133.  
  134.     return results
  135. end
  136.  
  137. -- Метатаблица для RadixTree
  138. local RadixTreeMetaTable = {
  139.     __index = RadixTreeMethods
  140. }
  141.  
  142. -- Функция для создания нового RadixTree
  143. function RadixTree(storageTable)
  144.     local tree = {}
  145.     tree.table = storageTable
  146.     setmetatable(tree, RadixTreeMetaTable)
  147.     return tree
  148. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement