Lua学习笔记(八):数据结构

  table是Lua中唯一的数据结构,其他语言所提供的数据结构,如:arrays、records、lists、queues、sets等,Lua都是通过table来实现,并且在Lua中table很好的实现了这些数据结构。

  1、数组

  在Lua中通过整数下标访问table中元素,既是数组,并且数组大小不固定,可动态增长。通常我们初始化数组时,就间接地定义了数组的大小,例如:

 1 a = {}        -- new array
 2 for i=1, 1000 do
 3     a[i] = 0
 4 end
 5
 6 --数组a的大小为1000,访问1-1000范围外的值,将返回nil。
 7 --数组下标可以根据需要,从任意值开始
 8 -- creates an array with indices from -5 to 5
 9 a = {}
10 for i=-5, 5 do
11     a[i] = 0
12 end

  然而习惯上,Lua的下标从1开始。Lua的标准库遵循此惯例,因此你的数组下标必须也是从1开始,才可以使用标准库的函数。

  我们可以用构造器在创建数组的同时初始化数组,这样数组的大小可以任意的大。

1 squares = {1, 4, 9, 16, 25, 36, 49, 64, 81}

  2、矩阵和多维数组

  Lua中有两种表示矩阵的方法,一是"数组的数组",也就是table的每个元素是另一个table。

--可以使用下面代码创建一个n行m列的矩阵
mt = {}            -- create the matrix
for i=1,N do
    mt[i] = {}        -- create a new row
    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

--这样实现的三角矩阵比起整个矩阵,仅适用一半的内存空间

  表示矩阵的另一方法,是将行和列组合起来。如果索引下标都是整数,通过第一个索引乘于一个常量(列)再加上第二个索引。

1 --看下面的例子实现创建n行m列的矩阵
2 mt = {}            -- create the matrix
3 for i=1,N do
4     for j=1,M do
5         mt[i*M + j] = 0
6     end
7 end

  如果索引是字符串,可用一个单字符将两个字符串索引连接起来构成一个单一的索引下标。

  3、链表

  Lua中用tables很容易实现链表,每一个节点是一个table,指针是这个表的一个域(field),并且指向另一个节点(table)。

 1 --要实现一个只有两个域:值和指针的基本链表
 2
 3 --根节点
 4 list = nil
 5
 6 --在链表开头插入一个值为v的节点
 7 list = {next = list, value = v}
 8
 9 --要遍历这个链表只需要
10 local l = list
11 while l do
12     print(l.value)
13     l = l.next
14 end

  其他类型的链表,像双向链表和循环链表类似的也是很容易实现的。在Lua中,很少情况下才需要这些数据结构,因为通常情况下有更简单的方式来替换链表。比如:我们可以用一个非常大的数组来表示栈,其中一个域n指向栈顶。

  4、队列和双向队列

  虽然可以使用Lua的table库提供的insert和remove操作来实现队列,但这种方式实现的队列针对大数据量时效率太低,有效的方式是使用两个索引下标,一个表示第一个元素,另一个表示最后一个元素。

 1 function ListNew ()
 2     return {first = 0, last = -1}
 3 end
 4
 5 --为了避免污染全局命名空间,我们重写上面的代码,将其放在一个名为list的table中
 6 List = {}
 7 function List.new ()
 8     return {first = 0, last = -1}
 9 end
10
11 --下面,我们可以在常量时间内,完成在队列的两端进行插入和删除操作了
12 function List.pushleft (list, value)
13     local first = list.first - 1
14     list.first = first
15     list[first] = value
16 end
17
18 function List.pushright (list, value)
19     local last = list.last + 1
20     list.last = last
21     list[last] = value
22 end
23
24 function List.popleft (list)
25     local first = list.first
26     if first > list.last then error("list is empty") end
27     local value = list[first]
28     list[first] = nil        -- to allow garbage collection
29     list.first = first + 1
30     return value
31 end
32
33 function List.popright (list)
34     local last = list.last
35     if list.first > last then error("list is empty") end
36     local value = list[last]
37     list[last] = nil        -- to allow garbage collection
38     list.last = last - 1
39     return value
40 end

  对严格意义上的队列来讲,我们只能调用pushright和popleft,这样以来,first和last的索引值都随之增加,幸运的是我们使用的Lua的table实现的,你可以访问数组的元素,通过使用下标从1到20,也可以16,777,216带16,777,236。另外Lua使用双精度表示数字,假定你每秒钟执行100万次插入操作,在数值溢出以前你的程序可以运行200年。

  5、集合和包

  假定你想列出在一段源代码中出现的所有标示符,某种程度上,你需要过滤掉那些语言本身的保留字。一些C程序员喜欢用一个字符串数组来表示,将所有的保留字放在数组中,对每一个标示符到这个数组中查找看是否为保留字,有时候为了提高查询效率,对数组存储的时候使用二分查找或者hash算法。

  Lua中表示这个集合有一个简单有效的方法,将所有集合中的元素作为下标存放在一个table里,不需要查找table,只需要测试看对于给定的元素,表的对应下标的元素值是否为nil。

 1 reserved = {
 2     ["while"] = true,        ["end"] = true,
 3     ["function"] = true,    ["local"] = true,
 4 }
 5
 6 for w in allwords() do
 7     if reserved[w] then
 8     -- `w‘ is a reserved word
 9     ...
10
11 --还可以使用辅助函数更加清晰的构造集合
12 function Set (list)
13     local set = {}
14     for _, l in ipairs(list) do set[l] = true end
15     return set
16 end
17
18 reserved = Set{"while", "end", "function", "local", }

Lua学习笔记(八):数据结构

时间: 2024-10-10 21:46:46

Lua学习笔记(八):数据结构的相关文章

Linux System Programming 学习笔记(八) 文件和目录管理

1. 文件和元数据 每个文件都是通过inode引用,每个inode索引节点都具有文件系统中唯一的inode number 一个inode索引节点是存储在Linux文件系统的磁盘介质上的物理对象,也是LInux内核通过数据结构表示的实体 inode存储相关联文件的元数据 ls -i 命令获取文件的inode number /* obtaining the metadata of a file */ #include <sys/types.h> #include <sys/stat.h>

Lua学习笔记(三):表的构造

构造器是创建和初始化表的表达式.表是Lua特有的功能强大的东西.最简单的构造函数是{},用来创建一个空表.可以直接初始化数组: 1 days = {"Sunday", "Monday", "Tuesday", "Wednesday", 2 "Thursday", "Friday", "Saturday"} Lua将“Sunday”初始化days[1](第一个元素索引为

[转]LUA 学习笔记

Lua 学习笔记 入门级 一.环境配置 方式一: 1.资源下载http://www.lua.org/download.html 2.用src中的源码创建了一个工程,注释调luac.c中main函数,生成了一个exe,直接可以测试lua了 方式二(推荐): 从https://code.google.com/p/luaforwindows/ 下载“LuaForWindows_v5.1.4-46.exe”,一键安装即可  二.执行 lua xxx.lua 三.注释 1.行注释格式:-- 2.块注释格式

angular学习笔记(八)

本篇介绍angular控制视图的显示和隐藏: 通过给元素添加ng-show属性或者ng-hide属性来控制视图的显示或隐藏: ng-show: 绑定的数据值为true时,显示元素,值为false时,隐藏元素 ng-hide: 绑定的数据值为true时,隐藏元素,值为false时,显示元素 (其实只要用到其中一个就可以了) 下面来看个简单的例子,点击按钮可以显示/隐藏元素: <!DOCTYPE html> <html ng-app> <head> <title>

Lua学习笔记(七):迭代器与泛型for

1.迭代器与闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功调用的状态,也就是他知道来自于哪里和将要前往哪里.闭包提供的机制可以很容易实现这个任务.记住:闭包是一个内部函数,它可以访问一个或者多个外部函数的外部局部变量.每次闭包的成功调用后这些外部局部变量都保存他们的值(状态).当然如果要创建一个闭包必须要创建其外部局部变量.所以一个典型的闭包的结构包含

Lua学习笔记9:多文件

一 终端中执行多个文件:-l 加入在文件一中定义了一个变量,在另一文件中输出这个变量,代码如下: --file1.lua num = 100 --file2.lua print(num) 终端输入(注意:不是lua命令行): lua -lfile1 -lfile2 注意:不要加上文件后缀名.lua 二 命令行中加载文件 --lib.lua function norm(x, y) local n2 = x^2 + y^2 return math.sqrt(n2) end function twic

lua学习笔记10:lua简单命令行

前面多次用了命令行,这次就好好学下命令行: 一 格式 lua [options][script][args] 二 具体命令 -e 直接将命令传个lua -l 加载一个文件 -i 进入交互模式 例如,终端输入: lua -e "print(math.sin(12))" lua学习笔记10:lua简单命令行,布布扣,bubuko.com

lua学习笔记11:lua中的小技巧

lua中的小技巧,即基础lua语言本身的特种,进行一个些简化的操作 一 巧用or x = x or v 等价于: if not x then x = v end 如果x为nil或false,就给他赋值为 二 三元运算符实现 a and b or c 类似C语言: a ? b : c and 的运算由优先级高于or lua学习笔记11:lua中的小技巧,布布扣,bubuko.com

马哥学习笔记八——LAMP编译安装之PHP及xcache

1.解决依赖关系: 请配置好yum源(可以是本地系统光盘)后执行如下命令: # yum -y groupinstall "X Software Development" 如果想让编译的php支持mcrypt扩展,此处还需要下载如下两个rpm包并安装之: libmcrypt-2.5.7-5.el5.i386.rpm libmcrypt-devel-2.5.7-5.el5.i386.rpm 2.编译安装php-5.4.13 首先下载源码包至本地目录. # tar xf php-5.4.13