Lua 之数据结构

Lua 之数据结构

数组

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

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

mt = {}
for i = 1, 10 do
    mt[i] = {}
    for j = 1, 10 do
        mt[i][j] = 0
    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=0, last=-1}
end

function queue.push(q, val)
    local last = q.last + 1
    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 + 1
    return val
end

q = queue.new()
for i=1,10,2 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+1] = 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) - 1, 1, -1 do
        if string.len(stack[i]) > string.len(stack[i+1]) 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[1], v[2]

        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+1] = 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=1, #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‘, 5, like={‘movie‘, ‘music‘}}

serialize(l)

输出内容:

{
 1 = 5,
 name = "cq",
 like = {
 1 = "movie",
 2 = "music",
}
,
}
时间: 2024-10-29 02:27:36

Lua 之数据结构的相关文章

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

table是Lua中唯一的数据结构,其他语言所提供的数据结构,如:arrays.records.lists.queues.sets等,Lua都是通过table来实现,并且在lua中table很好的实现了这些数据结构.--摘自:<Programming in Lua> 看以下代码,可以很清晰的明白Lua中表的使用: -- Lua中的表,table Config = {hello="Hello Lua",world="World"} -- 赋值方式1,以键=

Lua 常用数据结构

Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础.如数组.记录.线性表.队列和集合等,在Lua中都可以通过table来表示. 一.数组 在lua中通过整数下标访问表中的元素即可简单的实现数组.并且数组不必事先指定大小,大小可以随需要动态的增长. a = {} for i = 1,100 do a[i] = 0 end print("The length of array 'a' is " .. #a) squares = {1, 4, 9, 16, 25} pr

Lua 源码试读

开始看 Lua 源码也有段时间了,由于尝试用各种方式切入,效果均不是很理想,应该是个人内功不做所致.加上先阶段个人时间有限,现记录下断点,待到来日能力足够有兴趣时再来看. 初期探索: 0.由于第一次尝试读源码,开始时竟将源码按大小顺序排列,从小文件看起. 1.尝试从数据结构看起,看完了 Lua 的数据结构后对 Lua 的数据结构还是有种朦胧的感觉.然后尝试看 Lua 的 GC 终止. 2.尝试把 Lua 当作一个程序来看,从 main 函数开始读,函数调用层层深入下去...作为一个菜鸟,这注定是

Lua 与C/C++ 交互系列: Lua调用C/C++函数(4-2)

1.本文继续讲解Lua调用C/C++函数,本文的重点是通过metatable来实现Lua Code面向对象调用注册的C函数.本文中涉及的Environment 伪索引,userdata 以及GC 垃圾回收器的内容,都是简单的讲解.不作为本文的重点,这些内容都将在以后的章节中继续讲解. 2.本文涉及的到主要知识点补充说明. 2.1 void *lua_newuserdata (lua_State *L, size_t size); 函数说明 This function allocates a ne

项目用到了lua的哪些部分

昨天有位同事跟我说,我们的手游客户端(cocos2d-x lua binding)代码没有看到lua的特殊技巧,用起来跟其他语言差不多.<Programming in lua>毕竟有将近400多页,他想知道lua的语言特性都用在哪了.当其时回答不上来,现在来思考一下. 要解答他的疑问首先要解答的却是另外两个问题: 1.为什么我们的项目选用了lua? lua官网是这样介绍lua的:fast, portable, embeddable, powerful(but simple), small, f

Lua1.1 Lua 的设计和实现 (二)

转载出处:http://my.oschina.net/xhan/blog/309615 (接上篇) -------------------------------------- 实现 -------------------------------------- 扩展语言总是由应用程序以某种方式解释执行的.简单的扩展语言可以直接从源代码进行解释执行.另一方面,嵌入式语言通常是强大的编程语言,具有复杂的语法和语义.一个更有效的嵌入式语言实现技术是设计适合语言需求的虚拟机,编译扩展程序成虚拟机的字节码

CC3.2+Lua(2) ——Lua基础语法1

[唠叨] 首先,我已经默认你已经学过至少一门宿主语言了(C++.Java等),然后转向学习Lua. 因为51cto中对于Lua语言没有代码高亮,为了让代码看起来丰富多彩,我只好用截图了. 本节内容仅介绍Lua的简单基础语法,更多用法请百度:Lua中文教程 . Lua参考手册 . [学习感慨]     > 语句末尾不需要加分号 ;      > 语句块不是用花括号 { } , 而是 do 语句块 end 表示语句块的开始和结束.         而 花括号 {} 表示的为一个 表结构 .    

Lua之Lua数据结构-TTLSA(6)(转) good

一. tabletable是lua唯一的数据结构.table 是 lua 中最重要的数据类型. table 类似于 python 中的字典.table 只能通过构造式来创建.其他语言提供的其他数据结构如array.list等等,lua都是通过table来实现的.table非常实用,可以用在不同的情景下.最常用的方式就是把table当成其他语言的数组.实例1: 1 2 3 4 mytable = {} for index = 1, 100 do mytable[index] = math.rand

Lua数据结构

lua中的table不是一种简单的数据结构,它可以作为其他数据结构的基础,如:数组,记录,链表,队列等都可以用它来表示. 1.数组 在lua中,table的索引可以有很多种表示方式.如果用整数来表示table的索引,即可用table来实现数组,在lua中索引通常都会从1开始. --二维数组 n=10 m=10 arr={} for i=1,n do arr[i]={} for j=1,m do arr[i][j]=i*j end end for i=1, n do for j=1, m do i