lua学习笔记之数据结构

使用表来实现数组,记录,列表,队列,集合

1、数组

索引从1开始,并且连续。此时可以使用#表名来表示数组长度。索引不是从1开始的不能使用#

local a = {}
for i = 1, 1000 do
    a[i] = 0
end

print(#a)

输出:
1000

2、矩阵和多维数组

先创建矩阵(交错数组),然后创建行,通过这种方式可以创建三角矩阵

local N = 100
local M = 100
local mt = {}
for i = 1, N do
    local row = {}
    mt[i] = row
    for j = 1, M do
        row[j] = 0
    end
end

另外一种创建矩阵的方式是使用一维数组来表示。

local N = 100
local M = 100
local mt = {}
for i = 1, N do
    local aux = (i - 1) * M
    for j = 1, M do
        mt[aux + j] = 0
    end
   
end

矩阵运算

local N = 100
local M = 100
local K = 10
local c = {}
for i = 1, M do
    for j = 1, N do
        c[i][j] = 0
        for k = 1, K do
            c[i][j] = c[i][j] + a[i][k] * b[k][j]
        end
    end
end

矩阵运算的另外一种形式,先遍历b的行,前提是假定c的所有元素初始为0

local N = 100
local M = 100
local K = 10
local c = {}
for i = 1, M do
    for k = 1, K do
        for j = 1, N do
            c[i][j] = c[i][j] + a[i][k] * b[k][j]
        end
    end
end

 使用pair计算矩阵乘法

function mult(a, b)
    local c = {}
    for i = 1, #a do
        local resultline = {}
        for k, va in pairs(a[i]) do
            for j, vb in pairs(b[k]) do
                local res = (resultline[j] or 0) + va * vb
                resultline[j] = (res ~= 0) and res or nil
            end
        end
        c[i] = resultline
    end
    
    return c
end

3、链表

使用表形式{next = list,value=v}

list = nil

list = {next = list, value = 3}
local l = list
while l do
    print(l.value)
    l = l.next
end

输出:
3

4、队列及双端队列

使用表{first = 0,last=-1}形式表示双端队列

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] = value
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 error("list is empty") end
    local value = list[last]
    list[last] = nil
    list.last = last - 1
    return value
end

5、反向表

days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
revDays = {["Sunday"] = 1, ["Monday"] = 2, ["Tuesday"] = 3, ["Wednesday"] = 4, ["Thursday"] = 5,
           ["Friday"] = 6, ["Saturday"] = 7
            }
x = "Tuesday"
print(revDays[x])

输出:
3

也可以直接通过映射表来构建反向表

days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
revDays = {}
for k, v in pairs(days) do
    revDays[v] = k
end
x = "Tuesday"
print(revDays[x])

6、集合

在表中将集合中的元素作为索引。

reserved = {
    ["while"] = true, ["if"] = true,
    ["else"] = true, ["do"] = true
}

s = "while ok"
for w in string.gmatch(s, "[%a_][%w_]*") do
    if not reserved[w] then
        print(w)
    end
end

输出:
ok

可以通过列表构造集合

function Set(list)
    local set = {}
    for _, l in ipairs(list) do
        set[l] = true
    end

    return set
end

多重结合即multiset

function insert(bag, element)
    bag[element] = (bag[element] or 0) + 1
end

function remove(bag, element)
    local count = bag[element]
    bag[element] = (count and count > 1) and count - 1 or nil
end

7、字符串缓存

在存在多个字符串时,直接使用..拼接符,会影响性能。可以考虑使用表来存放字符串,通过table.concat来拼接字符串。

local t = {}

for line in io.lines() do
    t[#t + 1] = line .. "\n"
end

local s = table.concat(t)

8、图

表中包含两个字段,name表示结点名,adj表示邻接结点

local function name2node(graph, name)
    local node = graph[name]
    if not node then
        node = {name = name, adj = {}}
        graph[name] = node
    end

    return node
end

---从文件中读取图
function readgraph()
    local graph = {}
    for line in io.lines() do
        local namefrom, nameto = string.match(line, "(%S+"%s+(%S+))
        local from = name2node(graph, namefrom)
        local to = name2node(graph, nameto)
        from.adj[to] = true
    end

    return graph
end

function findpath(curr, to, path, visited)
    path = path or {}
    visited = visited or {}
    if visited[curr] then
        return nil
    end

    visited[curr] = true
    path[#path + 1] = curr
    if curr == to then
        return path
    end

    for node in pairs(curr.adj) do
        local p = findpath(node, to, path, visited)
        if p then
            return p
        end
    end

    table.remove(path)
end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值