使用表来实现数组,记录,列表,队列,集合
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