LUA implementa la estructura de datos: cola de dos extremos

prefacio

La estructura de datos incorporada de Lua es generalmente una: tabla. Sin embargo, muchas veces nuestro negocio requiere varias estructuras, y estas estructuras se pueden escribir en base a tablas.

método de cola de dos extremos

Hay varios métodos proporcionados por la cola de dos extremos:

  • ve a la izquierda
  • Excluido
  • ve a la derecha
  • inmediatamente

La estructura proporcionada por "programador en lua":

function listNew()
  return {
    
    first = 0, last = -1}
end

function pushFirst(list, value)
  local first = list.first - 1
  list.first = first
  list[first] = value
end

function pushLast(list, value)
  local last = list.last + 1
  list.last = last
  list[last] = last
end

function popFirst(list)
  local first = list.first
  if first > list.last then error("list is empty") end
  local value = list[first]
  list[first] = nil
  list.first = first + 1
  return value
end

function popLast(list)
  local last = list.last
  if list.first > last then errot("list is empty") end
  local value = list[last]
  list[last] = nil
  list.last = last - 1
end

Para facilitar nuestras pruebas, necesitamos implementar un método para imprimir el valor interno:

function foreach(list, func)
   for i = list.first, list.last do
       if func(list[i]) then 
           break
       end
end

-- 需要注意的是如果是table,用print可能无法很好的了解到内部的内容
function printQ(list)
    foreach(list, print)
end

El método de llamada es más o menos el siguiente:

local list = listNew()
for i = 1, 10 do
    pushFirst(list, i)
end

printQ(list)

versión del paquete

Esta versión encapsula la versión anterior, cree un nuevo archivo llamado List.lua:

local List = {
    
    }
List.__index = List

function List:new()
    local self = {
    
    first = 0, last = -1}
    return setmetatable(self, List)
end

local function _itor(self, k)
    return k <= self.last - self.first and k+1 or nil, self[self.first+k]
end

function List:__pairs()
    return _itor, self, 0
end

function List:pushFirst(value)
    local first = self.first - 1
    self.first = first
    self[first] = value
end

function List:pushLast(value)
    local last = self.last + 1
    self.last = last
    self[last] = value
end

function List:popFirst()
    local first = self.first
    if first > self.last then error("list is empty") end
    local value = self[first]
    self[first] = nil        -- to allow garbage collection
    if first == self.last then
        self.first = 0
        self.last = -1
    else
        self.first = first + 1
    end
    return value
end

function List:popLast ()
    local last = self.last
    if self.first > last then error("list is empty") end
    local value = self[last]
    self[last] = nil         -- to allow garbage collection
    if last == self.first then
        self.first = 0
        self.last = -1
    else
        self.last = last - 1
    end
    return value
end

function List:empty()
    return (self.first > self.last)
end

function List:length()
    return (self.first > self.last) and 0 or (self.last-self.first+1)
end

-- should not change the self in func
-- func return break or not
function List:foreach(func, right_first)
    if right_first then
        for i = self.last, self.first, -1 do
            if func(self[i]) then break end
        end
    else
        for i = self.first, self.last do
            if func(self[i]) then break end
        end
    end
end

function List:clear()
    if not self:empty() then
        for i = self.first, self.last do
            self[i] = nil
        end
    end
    self.first = 0
    self.last = -1
end

function List:left()
    local first = self.first
    if first > self.last then error("list is empty") end
    return self[first]
end

function List:right()
    local last = self.last
    if self.first > last then error("list is empty") end
    return self[last]
end

function List:to_table()
    local res = {
    
    }    
    for i = self.first, self.last do
        table.insert(res, self[i])
    end
    return res
end

List.__ipairs = List.__pairs
List.len = List.length
List.size = List.length
List.push = List.pushLast
List.pop = List.popFirst
return List

En términos de métodos de llamada, los métodos de llamada específicos son los siguientes:

local List = require("List")
local list = List:new()
for i = 1, 10 do
    list:push(i)
end

list:foreach(print)

Supongo que te gusta

Origin blog.csdn.net/sayWhat_sayHello/article/details/115400461
Recomendado
Clasificación