您的位置:首页 > 理论基础 > 数据结构算法

Lua学习笔记 第十一章 数据结构

2014-08-25 17:41 274 查看
Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础。
如数组、链表、队列等。
 
11.1数组
使用整数来索引table即可在lua中实现数组。因此,数组没有一个固定的大小,可以根据需要增长。如:
a = {}
for i=1, 1000 do
    a[i] = 0
end
也可以使用0、1或者其它任意值来作为数组的起始索引。但如果数组的索引不以1开始,那就无法使用
长度操作符#了。通过table的构造式,可以在语句表达式中创建并初始化数组:
squares = {1, 4, 9, 16, 25, 36, 49, 64,81}
 
11.2矩阵与多维数组
在Lua中,有两种方式来表示矩阵。第一种是使用一个"数组的数组",也就是说一个table中的每个元素是
另一个table。例如,使用以下代码创建N*M的零矩阵:
mt = {}                 --
创建矩阵
for i=1, N do

    mt[i] = {}          --创建一个新行
    for j=1, M do
        mt[i][j] = 0
    end
end
第二种方式是将两个索引合并为一个索引。如果两个索引是整数,可以将第一个索引乘以一个适当的常量,
并加上第二个索引。以下代码使用这种方法创建N*M的零矩阵:
mt = {}
for i=1, N do

    for j=1, Mdo

        mt[(i-1)*M + j] = 0
end
end
但如果索引是字符串,那么可以把索引拼接起来,中间使用一个字符来分隔。例如,使用字符串s和t来索
引一个矩阵,可以通过m[s .. ":" ..t]。其中s和t都不能包含冒号。
 
11.3链表
由于table是动态的实体,所以在Lua中实现链表是很方便的。
每个节点以一个table来表示,其中每个节点包含两个字段:next
和 value。先创建一个用作列表头节点的变量:
list = nil                          --
不断在表头插入一个元素,元素值为v:
list =  {next =list, value =v}
遍历此链表:
local l = list
while l do
   <访问l.value>
   l = l.next
end
 
11.4队列与双向队列
在Lua中实现队列的一种简单方法是使用table库中的函数insert和remove。这两个函数
可以在一个数组的任意位置插入或删除元素,并且根据操作要求移动后续元素。但对于较大的结构,
移动的开销是很大的。一种更高效的实现是使用两个索引,分别用于首尾的两个元素。为了避免污染
全局名称空间,将在一个table内部定义所有的队列操作——示例:
List = {}
function List.new()
return {first = 0,last = -1}

c210
end
在两端插入或删除元素的函数:
function List.pushfirst(list, value)
    local first =list.first - 1
    list.first =first
    list[first] =value
end
function List.pushlast(list, value)
    local last = list.last+ 1
    list.last =last

    list[last] =value
end
 
function List.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
fuction List.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
如果希望该结构能严格地遵循队列的操作规范,那么只调用pushlast
和 popfirst就可以了,
这样first
和 last 都会不断地增长。
 
11.5
集合与无序组(bug) p99
 
11.6
字符串缓冲
假设正在编写一段关于字符串的代码,例如正在逐行地读取一个文件。典型的读取代码是这样的:
local buff = ""
for line in io.lines() do

    buff = buff.. line .. "\n"
end
这段代码看似可以正常工作,但如果面对较大的文件时,它会导致极大的性能开销。
解决方案:
一是,当需要读取整个文件时,Lua提供了io.read("*all")选项,这样便可以一次性读取整个文件。
二是,在Lua中我们可以将一个table作为字符串缓冲。关键是使用函数table.concat,它会将给定列表
中的所有字符串连接起来,并返回连接的结果。示例代码——
local t = {}
for line in io.lines() do

    t[#t+1] =line .. "\n"
end
local s = table.concat(t)
table.concat函数还还以有第二个可选的参数,可以指定一个插在字符串中间的分隔符。
有了这个分隔符就不必在每行后插入一个"\n"了。
for line in io.lines() do

    t[#t+1] =line
end
s = table.concat(t,"\n") .. "\n"

这样需要在结尾处添加一个换行符,在最后一次连接时复制了整个结果字符串,而这时字符串
已经相当长了。解决方法,欺骗concat,在t后面添加一个空字符串:
t[#t+1] = ""
s = table.concat(t, "\n")
 
11.7
图 p102
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lua 脚本