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

Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础。

如数组、链表、队列等。

 

11.1数组

使用整数来索引table即可在lua中实现数组。因此,数组没有一个固定的大小,可以根据需要增长。如:

a = {}

for i=1, 1000 do

    a[i] = 0

end

也可以使用01或者其它任意值来作为数组的起始索引。但如果数组的索引不以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

但如果索引是字符串,那么可以把索引拼接起来,中间使用一个字符来分隔。例如,使用字符串st来索

引一个矩阵,可以通过m[s .. ":" ..t]。其中st都不能包含冒号。

 

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库中的函数insertremove。这两个函数

可以在一个数组的任意位置插入或删除元素,并且根据操作要求移动后续元素。但对于较大的结构,

移动的开销是很大的。一种更高效的实现是使用两个索引,分别用于首尾的两个元素。为了避免污染

全局名称空间,将在一个table内部定义所有的队列操作——示例:

List = {}

function List.new()

return {first = 0,last = -1}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值