1、 table是Lua中唯一的数据结构,其他语言提供的其他数据比如:arrays、records、lists、queues、sets等,Lua都是通过table来实现的。
2、 数组
在Lua中通过整数下标访问表中的元素即可简单的实现数组,并且数组不必事先指定大小,大小可以随需要动态的增长。
通常我们初始化数组的时候就间接的定义了数组的大小,例如:
a = {}
for i = 1,1000 do
a[i] = 0
end
通过初始化,数组a的大小已经确定为1000,企图访问1-1000以外的下标对应的值将返回nil。你可以根据需要定义数组的下标从0,1或者其他的数值,例如:
a = {}
for i = -5,5 do
a[i] = 0
end
然而在lua中习惯上数组的下标从1开始,lua的标准库与此习惯保持一致,因此如果你的数组下标也是从1开始你就可以直接使用标准库的函数,否则无法直接使用。我们可以再用构造器在创建数组的同时并初始化数组:
Squares={1,4,9,16,25,36,49,64,81}
3、 阵和多维数组
Lua中主要有两种表示矩阵的方法,第一种是用数组的数组表示。也就是说一个表的元素是另一个表。例如我们创建一个n行m列的矩阵:
mt ={}
for i=1,N do
mt[i] = {}
for j = 1,M do
mt[i][j] = 0
end
end
由于lua中table是一个对象,所以对于每一行我们必须显示的创建一个table,这看起来比c沉余,另一方面它也提供了蛮多的灵活性,例如可以修改前面的例子来创建一个三角矩阵:
for j = 1,M do
改成 for j=1,i do
这样实现的三角矩阵比起整个矩阵,仅仅使用一半的内存空间。第二个中表示矩阵的方法是将行和列组合起来,如果索引下标都是整数,通过第一个索引乘以一个常量(列)再加上第二个索引,看下面的例子实现创建n行m列的矩阵:
mt = {}
for i =1,N do
for j =1,M do
mt[i*M+j] = 0
end
end
4、 链表
Lua中用tables很容易实现链表,每一个节点是一个table,指针是这个表的一个域,并且指向另一个table。例如,要实现一个只有两个域:值或指针的基本链表,代码如下:
跟节点
list = nil
在链表开头插入一个值为v的节点:
list = {next = list,value = v}
要遍历这个链表只需要:
Local l = list
While l do
print(l.value)
l = l.next
end
5、 队列和双端队列
虽然可以使用Lua的table库提供的insert和remove操作实现队列,但这种方式实现的队列针对大数据时效率太低,有效的方式是使用两个索引下标,一个表示第一个元素,另一个表示最后一个元素。
Function ListNew()
Return (first = 0,last = -1)
end
为了避免污染全局命名空间,我们重写上面的代码,将其放在一个名为list的table中:
List = {}
function List.new()
return (first =0,last = -1)
end
下面,我们可以在常量时间内,完成在队列的两端进行插入和删除操作。
function List.pushleft(list,value)
local first = list.first-1
list.first = first
list[first] = value
end
function List.pushright (list,value)
local last = list.last+1
list.last = last
list[last] = value
end
function List.poleft(list)
local first = list.first
if first>list.last then error(“list is empty”)
local value = list[first]
list[first] = nil
list.first = first+1
return value
end
function List.popright(list)
local last = list.last
if list.first>last then error(“list is empty”)
local value = list[last]
list[last] = nil
list.last = last-1
return value
end
6、 集合和包
假定你像列出在一段源代码出现的所有标识符,某种程度上,你需要过滤掉那些语言本身的保留字。
Lua中表示这个集合有一个简单有效的方法,将所有集合中的元素作为下标存放在一个table里,下面不需要查找table,只需要测试看对于给定的元素,表的对应下标的元素是否为nil,例如:
reserved = {
[“while”] = true,
[“end”] = true,
[“function”] = true,
[“local”] = true,
}
for w inallowords() do
if reserved[w] then
--‘w’is a reservedword
…
还可以使用辅助函数更加清晰的构造集合:
function Set(list)
local Set = {}
for _,l in ipairs[list] do set[1] =true end
return set
end
reserved = Set{“while”,”end”,”function”,”local”,}