006 动态数组(lua)

在Lua中,没有类的概念,因为它是基于原型的语言。不过,我们可以使用表(table)来模拟类和对象
Lua中的数组索引是从1开始的,而不是从0开始,
Lua的表是动态大小的,因此我们没有在Lua实现中强制数组的容量。
我们在Array.new函数中初始化了一个具有指定容量大小的数组,并且当尝试添加超过该容量的元素时,会抛出一个错误。在实际Lua使用中,通常不需要这样做,因为Lua表会自动扩展。此外,我们在移除元素时显式地将最后一个元素设置为nil,以避免潜在的内存泄漏,这是Lua中管理内存的一种好习惯。

初步准备

-- 这里创建了一个空表Array,它将被用作自定义数组类的原型。
-- __index元方法用于当访问表中不存在的字段时,Lua会调用这个元方法来查找值。
Array = {}  
Array.__index = Array  

-- 构造函数
-- 这个函数是Array的构造函数,用于创建一个新的Array实例。
-- setmetatable函数设置了self的元表为Array,这样self就可以访问Array中定义的方法。

function Array.new(capacity)  
    if capacity == nil then  
        capacity = 10  
    end  
    local self = {  
        data = {},  
        size = 0,  
        capacity = capacity  
    }  
    setmetatable(self, Array)  
    for i = 1, capacity do  
        self.data[i] = nil  
    end  
    return self  
end  

-- 成员方法
-- 在Lua中,冒号:语法用于定义对象的方法
-- 这个方法返回数组的大小。self关键字代表调用该方法的对象实例。
function Array:getSize()  
    return self.size  
end  
  
function Array:getCapacity()  
    return self.capacity  
end  
  
function Array:isEmpty()  
    return self.size == 0  
end  
  
function Array:addLast(e)  
    self:add(self.size + 1, e)  
end  
  
function Array:addFirst(e)  
    self:add(1, e)  
end  
  
function Array:add(index, e)  
    if self.size == self.capacity then  
        error("Add failed. Array is full.")  
    end  
  
    if index < 1 or index > self.size + 1 then  
        error("Add failed. Require index >= 1 and index <= size + 1.")  
    end  
  
    for i = self.size, index, -1 do  
        self.data[i + 1] = self.data[i]  
    end  
    self.data[index] = e  
    self.size = self.size + 1  
end  
  
function Array:get(index)  
    if index < 1 or index > self.size then  
        error("Get failed. Index is illegal.")  
    end  
    return self.data[index]  
end  
  
function Array:set(index, e)  
    if index < 1 or index > self.size then  
        error("Set failed. Index is illegal.")  
    end  
    self.data[index] = e  
end  
  
function Array:contains(e)  
    for i = 1, self.size do  
        if self.data[i] == e then  
            return true  
        end  
    end  
    return false  
end  
  
function Array:find(e)  
    for i = 1, self.size do  
        if self.data[i] == e then  
            return i  
        end  
    end  
    return -1  
end  
  
function Array:remove(index)  
    if index < 1 or index > self.size then  
        error("Remove failed. Index is illegal.")  
    end  
  
    local ret = self.data[index]  
    for i = index, self.size - 1 do  
        self.data[i] = self.data[i + 1]  
    end  
    self.size = self.size - 1  
    self.data[self.size + 1] = nil  -- Explicitly nil the last element to avoid memory leak  
    return ret  
end  
  
function Array:removeFirst()  
    return self:remove(1)  
end  
  
function Array:removeLast()  
    return self:remove(self.size)  
end  
  
function Array:removeElement(e)  
    local index = self:find(e)  
    if index ~= -1 then  
        self:remove(index)  
    end  
end  
  
function Array:toString()  
    local res = "Array: size = " .. self.size .. ", capacity = " .. self.capacity .. "\n["  
    for i = 1, self.size do  
        res = res .. self.data[i]  
        if i ~= self.size then  
            res = res .. ", "  
        end  
    end  
    res = res .. "]"  
    return res  
end  
  
-- Example usage:  
local arr = Array.new(5)  
arr:add(1, 10)  
arr:add(2, 20)  
arr:add(3, 30)  
print(arr:toString())  -- Output: Array: size = 3, capacity = 5 [10, 20, 30]

实际应用

由于Lua的表会自动进行扩展,我们不需要像在Java中那样显式地管理数组的容量。
在Lua中,我们通常使用ipairs来遍历数组部分(即,具有连续整数键的部分)的表。
由于Lua的表本身就是动态的,我们不需要像Java中那样处理数组的扩容。


Array = {}  
Array.__index = Array  
  
function Array.new()  
    local self = {}  
    self.size = 0  
    self.data = {}  
    setmetatable(self, Array)  
    return self  
end  
  
function Array:getSize()  
    return self.size  
end  
  
function Array:isEmpty()  
    return self.size == 0  
end  
  
function Array:addLast(e)  
    table.insert(self.data, e)  
    self.size = self.size + 1  
end  
  
function Array:addFirst(e)  
    table.insert(self.data, 1, e)  
    self.size = self.size + 1  
end  
  
function Array:add(index, e)  
    if index < 1 or index > self.size + 1 then  
        error("Add failed. Require index >= 1 and index <= size + 1.")  
    end  
    table.insert(self.data, index, e)  
    self.size = self.size + 1  
end  
  
function Array:get(index)  
    if index < 1 or index > self.size then  
        error("Get failed. Index is illegal.")  
    end  
    return self.data[index]  
end  
  
function Array:set(index, e)  
    if index < 1 or index > self.size then  
        error("Set failed. Index is illegal.")  
    end  
    self.data[index] = e  
end  
  
function Array:contains(e)  
    for _, v in ipairs(self.data) do  
        if v == e then  
            return true  
        end  
    end  
    return false  
end  
  
function Array:find(e)  
    for i, v in ipairs(self.data) do  
        if v == e then  
            return i  
        end  
    end  
    return -1  
end  
  
function Array:remove(index)  
    if index < 1 or index > self.size then  
        error("Remove failed. Index is illegal.")  
    end  
    local ret = table.remove(self.data, index)  
    self.size = self.size - 1  
    return ret  
end  
  
function Array:removeFirst()  
    return self:remove(1)  
end  
  
function Array:removeLast()  
    return self:remove(self.size)  
end  
  
function Array:removeElement(e)  
    local index = self:find(e)  
    if index ~= -1 then  
        self:remove(index)  
    end  
end  
  
function Array:toString()  
    local res = "Array: size = " .. self.size .. "\n["  
    for i, v in ipairs(self.data) do  
        res = res .. v  
        if i ~= self.size then  
            res = res .. ", "  
        end  
    end  
    res = res .. "]"  
    return res  
end  
  
-- Example usage:  
local arr = Array.new()  
arr:add(1, 10)  
arr:add(2, 20)  
arr:add(3, 30)  
print(arr:toString())  -- Output: Array: size = 3 [10, 20, 30]

Array = {}  
Array.__index = Array  
  
function Array.new(capacity)  
    local self = {}  
    setmetatable(self, Array)  
  
    -- Initialize the array-like table  
    self.data = {}  
    self.size = 0  
    self.capacity = capacity or 10  
  
    return self  
end  
  
function Array:getSize()  
    return self.size  
end  
  
function Array:getCapacity()  
    return self.capacity  
end  
  
function Array:isEmpty()  
    return self.size == 0  
end  
  
function Array:addLast(element)  
    self:add(self.size + 1, element)  
end  
  
function Array:addFirst(element)  
    table.insert(self.data, 1, element)  
    self.size = self.size + 1  
    -- Handle capacity increase if needed (omitted for simplicity)  
end  
  
function Array:add(index, element)  
    if index < 1 or index > self.size + 1 then  
        error("Index out of bounds")  
    end  
  
    table.insert(self.data, index, element)  
    self.size = self.size + 1  
  
    -- Handle capacity increase if needed (omitted for simplicity)  
end  
  
function Array:get(index)  
    if index < 1 or index > self.size then  
        error("Index out of bounds")  
    end  
  
    return self.data[index]  
end  
  
function Array:set(index, element)  
    if index < 1 or index > self.size then  
        error("Index out of bounds")  
    end  
  
    self.data[index] = element  
end  
  
function Array:remove(index)  
    if index < 1 or index > self.size then  
        error("Index out of bounds")  
    end  
  
    local element = table.remove(self.data, index)  
    self.size = self.size - 1  
    return element  
end  
  
function Array:removeFirst()  
    return self:remove(1)  
end  
  
function Array:removeLast()  
    return self:remove(self.size)  
end  
  
function Array:toString()  
    local str = "Array: size = " .. self.size .. ", capacity = " .. self.capacity .. "\n["  
    for i = 1, self.size do  
        str = str .. tostring(self.data[i])  
        if i ~= self.size then  
            str = str .. ", "  
        end  
    end  
    str = str .. "]"  
    return str  
end  
  
-- Usage example  
local arr = Array.new()  
arr:addLast(10)  
arr:addLast(20)  
arr:addFirst(5)  
print(arr:toString())
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简 洁 冬冬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值