Lua 之数据结构

数组

通过整数下标访问的table中的元素,即是数组,下标默认从1开始。

一个创建二维数组的例子:

mt = {}
for i = , do
mt[i] = {}
for j = , do
mt[i][j] =
end
end

链表

list = nil
list = {next=list, value="world"}
list = {next=list, value="hello"} local l = list while l do
print(l.value)
l = l.next
end

队列

queue = {}

function queue.new()
return {first=, last=-}
end function queue.push(q, val)
local last = q.last +
q.last = last
q[last] = val
end function queue.pop(q)
local first = q.first if first > q.last then
error("queue is empty")
end local val = q[first]
q[first] = nil
q.first = q.first +
return val
end q = queue.new()
for i=,, do
queue.push(q, i)
end for i=q.first,q.last do
print(queue.pop(q))
end

集合

类似于python的set结构,例如:

function set(list)
local s = {}
for _, n in ipairs(list) do
s[n] = true
end
return s
end reserved = set{"beijing", "xian"}
reserved.beijing -- true
reserved.shanghai -- nil

字符串缓冲

假如需要读取一个文件的内容,常用的方式如下:

local buff = ""

for line in io.lines() do
buff = buff .. line .. "\n"
end print(buff)

假设每行有20 bytes,已读了2500行,那么buff现在就是50000B,当Lua做字符串连接时,就新建一个50020B的新字符串,并从buff中复制了50000B到这个新字符串。这样,对于后面的每一行,Lua都需要移动更多的内存,显然,这样做效率是比较低的。

下面是一个改进的版本,利用table做缓冲,最后利用table.concat将所有行连接起来:

local t = {}

for line in io.lines() do
t[#t+] = line
end local s = table.concat(t, '\n')

那么问题来了,concat的内部工作原理是什么呢,它在连接字符串的时候如何做到高效运行呢?

将每次需要连接的字符串压入堆栈,如果新加入的字符串比栈顶字符串更大,就将两者连接。然后,再将连接后的新字符串与更下面的字符串比较,如果是新建字符串更长的话,则再次连接它们。这样的连接一直向下延续应用,直到遇到一个更大的字符串或者达到了栈底。

function NewStack()
return {""}
end function push(stack, s)
table.insert(stack, s) for i = table.getn(stack) - , , - do
if string.len(stack[i]) > string.len(stack[i+]) then
break
end stack[i] = stack[i] .. table.remove(stack)
end
end local s = NewStack()
for line in io.lines() do
push(s, line .. "\n")
end

下面是一个广度优先遍历有向图的例子,其中raw描述了图的所有边,每个边有两个点——起点、终点。

用了一个table来表示点,它有两个字段,name和adj,name表示该点的名称,adj表示它的终点。

raw = {
{'A','B'},
{'A','F'},
{'B','C'},
{'B','I'},
{'B','G'},
{'F','G'},
{'F','E'},
{'C','I'},
{'C','D'},
{'I','D'},
{'G','H'},
{'G','D'},
{'H','E'},
{'H','D'},
{'E','D'},
} local function name2node(graph, name)
if not graph[name] then
graph[name] = {name=name, adj={}}
end
return graph[name]
end local function readgraph()
local graph = {}
for _,v in pairs(raw) do
local namefrom, nameto = v[], v[] 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 -- no path
return nil
end visited[curr] = true
path[#path+] = curr if curr == to then -- be found
return path
end for node in pairs(curr.adj) do -- recursive
local p = findpath(node, to, path, visited)
if p then return p end
end path[#path] = nil
end function printpath(path)
for i=, #path do
print(path[i].name)
end
end g = readgraph()
a = name2node(g, 'A')
b = name2node(g, 'D')
p = findpath(a, b)
if p then printpath(p) end

序列化

打印一个lua对象:

function serialize(o)
if type(o) == "number" then
io.write(o)
elseif type(o) == "string" then
io.write(string.format("%q", o))
elseif type(o) == "table" then
io.write("{\n")
for k,v in pairs(o) do
io.write(" ",k," = ")
serialize(v)
io.write(",\n")
end
io.write("}\n")
else
error("cannot serialize a " .. type(o))
end
end local l = {name='cq', , like={'movie', 'music'}} serialize(l)

输出内容:

{
= ,
name = "cq",
like = {
= "movie",
= "music",
}
,
}

Lua 之数据结构的更多相关文章

  1. Cocos2d-x 脚本语言Lua基本数据结构-表(table)

    Cocos2d-x 脚本语言Lua基本数据结构-表(table) table是Lua中唯一的数据结构.其它语言所提供的数据结构,如:arrays.records.lists.queues.sets等. ...

  2. cocos2dx解析lua table数据结构 简易版.

    之前一直用xml填配置, cocos2dx自带了xml解析接口, 非常方便. 但是, 接口好用也改变不了xml的结构字符太多, 书写麻烦, 乱七八糟的事实. 很早就想换lua, 无奈引擎没有现成接口, ...

  3. Lua 的数据结构

    1. Arrays: 注意 #(data), # 加上 table名字 == size of data = {}; , do --行 , do --列 data[(y-)*+x] = (y-)*+x; ...

  4. 项目用到了lua的哪些部分

    昨天有位同事跟我说,我们的手游客户端(cocos2d-x lua binding)代码没有看到lua的特殊技巧,用起来跟其他语言差不多.<Programming in lua>毕竟有将近4 ...

  5. [转]编写高性能的Lua代码

    昨天晚上闲来无事,看室友在电脑上挂机玩游戏,用的一个辅助脚本,以为是lua写的脚本在跑,实际调查发现是按键精灵的脚本. 于是在网上找相关Lua开发游戏脚本的案例,看到一个人的博客,内容很不错,学到了很 ...

  6. Lua学习----零碎知识点

    Jit(just in time) 动态即时编译,边运行时边编译---->lua (主要是面向进程) Aot(ahead of time) 静态提前编译,运行前编译---->C#(主要是面 ...

  7. Lua设计与实现--读书笔记

    目录 lua简介 一种通用的数据类型:lua_TValue 字符串 Table lua实现一个队列 lua简介 C++底层核心模块,暴露核心接口给lua脚本层,网络的收发都在c++层完成,本书简述lu ...

  8. 让你的Python代码更加pythonic

    http://wuzhiwei.net/be_pythonic/ 何为pythonic? pythonic如果翻译成中文的话就是很python.很+名词结构的用法在中国不少,比如:很娘,很国足,很CC ...

  9. lua解析脚本过程中的关键数据结构介绍

    在这一篇文章中我先来介绍一下lua解析一个脚本文件时要用到的一些关键的数据结构,为将来的一系列代码分析打下一个良好的基础.在整个过程中,比较重要的几个源码文件分别是:llex.h,lparse.h.l ...

随机推荐

  1. 使用AOP 实现多数据源 切换

    多数据源的实现,这里就来个实例吧 1.在 spring 的配置文件中数据源信息 <?xml version="1.0" encoding="UTF-8"? ...

  2. 510C

    510C 拓扑排序:将那些受影响的字母拓扑排序,其后的输出 #include<iostream> #include<cstdio> #include<vector> ...

  3. mysql-数据类型与java数据类型转化工具类

    mysql和java对照表 类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述             VARCHAR L+N VARCHAR java.lang.Stri ...

  4. cygwin-介绍-安装

    初学linux时,最头疼的是,因为windows和linux各有优点,各有用途,所以只能麻烦的在两者之间切换,不断的重启.开机时也麻烦,因为初学者大多数使用windows,装了linux后,开机会自动 ...

  5. 系统间通信(8)——通信管理与RMI 上篇

    1.概述 在概述了数据描述格式的基本知识.IO通信模型的基本知识后.我们终于可以进入这个系列博文的重点:系统间通信管理.在这个章节我将通过对RMI的详细介绍,引出一个重要的系统间通信的管理规范RPC, ...

  6. 【CodeForces 699B】One Bomb

    r[i],c[i]分别表示第i行有几个*,第i列有几个*. 枚举每个位置如果c[i]+r[j]-(本身是不是*)==总*数,则该位置即为答案. #include<cstdio> #incl ...

  7. Shiro-认证

    认证流程: 1. 获取当前的 Subject. 调用 SecurityUtils.getSubject();2. 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subject 的 isAut ...

  8. Scala特性: 隐式转换

    1.隐式转换特征: 1)隐式参数的用法 · 获取可能的预期类型 · 获取预期类型,并且拥有预期类型的行为 · 对信息进行补充说明(一般用函数做隐式参数的比较多) 2)隐式类: 3)隐式method:

  9. js事件委托的方式绑定详解

    js事件绑定 事件绑定,这里使用了冒泡的原理,从点击的元素开始,递归方式的向父元素传播事件,这样做的好处是对于大量要处理的元素,不必为每个元素都绑定事件,只需要在他们的父元素上绑定一次即可,提高性能. ...

  10. androidstudio 之 svn配置 汇总

    http://www.cnblogs.com/shaocm/p/4182380.html https://www.zhihu.com/question/32298079 http://www.it16 ...