Step By Step(Lua数据结构)

Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础。如数组、记录、线性表、队列和集合等,在Lua中都可以通过table来表示。       
    1. 数组:
    使用整数来索引table即可在Lua中实现数组。因此,Lua中的数组没有固定的大小,如:

1 a = {}
2 for i = 1, 1000 do
3 a[i] = 0
4 end
5 print("The length of array 'a' is " .. #a)
6 --The length of array 'a' is 1000

在Lua中,可以让任何数作为数组的起始索引,但通常而言,都会使用1作为其起始索引值。而且很多Lua的内置功能和函数都依赖这一特征,因此在没有充分理由的前提下,尽量保证这一规则。下面的方法是通过table的构造器来创建并初始化一个数组的,如:
    squares = {1, 4, 9, 16, 25}

    2. 二维数组:
    在Lua中我们可以通过两种方式来利用table构造多维数组。其中,第一种方式通过“数组的数组”的方式来实现多维数组的,即在一维数组上的每个元素也同样为table对象,如:

 
1 mt = {}
2 for i = 1, N do
3 mt[i] = {}
4 for j = 1, M do
5 mt[i][j] = i * j
6 end
7 end
 

第二种方式是将二维数组的索引展开,并以固定的常量作为第二维度的步长,如:

1 mt = {}
2 for i = 1, N do
3 for j = 1, M do
4 mt[(i - 1) * M + j] = i * j
5 end
6 end

3. 链表:
    由于table是动态的实体,所以在Lua中实现链表是很方便的。其中,每个结点均以table来表示,一个“链接”只是结点中的一个字段,该字段包含对其它table的引用,如:

 
 1 list = nil
2 for i = 1, 10 do
3 list = { next = list, value = i}
4 end
5
6 local l = list
7 while l do
8 print(l.value)
9 l = l.next
10 end
 

4. 队列与双向队列:
    在Lua中实现队列的简单方法是使用table库函数insert和remove。但是由于这种方法会导致后续元素的移动,因此当队列的数据量较大时,不建议使用该方法。下面的代码是一种更高效的实现方式,如:

 1 List = {}
2
3 function List.new()
4 return {first = 0, last = -1}
5 end
6
7 function List.pushFront(list, value)
8 local first = list.first - 1
9 list.first = first
10 list[first] = value
11 end
12
13 function List.pushBack(list, value)
14 local last = list.last + 1
15 list.last = last
16 list[last] = value
17 end
18
19 function List.popFront(list)
20 local first = list.first
21 if first > list.last then
22 error("List is empty")
23 end
24 local value = list[first]
25 list[first] = nil
26 list.first = first + 1
27 return value
28 end
29
30 function List.popBack(list)
31 local last = list.last
32 if list.first > last then
33 error("List is empty")
34 end
35 local value = list[last]
36 list[last] = nil
37 list.last = last - 1
38 return value
39 end
 

5. 集合和包(Bag):
    在Lua中用table实现集合是非常简单的,见如下代码:
    reserved = { ["while"] = true, ["end"] = true, ["function"] = true, }
    if not reserved["while"] then
        --do something
    end
    在Lua中我们可以将包(Bag)看成MultiSet,与普通集合不同的是该容器中允许key相同的元素在容器中多次出现。下面的代码通过为table中的元素添加计数器的方式来模拟实现该数据结构,如:

 
1 function insert(bag, element)
2 bag[element] = (bag[element] or 0) + 1
3 end
4
5 function remove(bag, element)
6 local count = bag[element]
7 bag[element] = (count and count > 1) and count - 1 or nil
8 end
 

6. StringBuilder:
    如果想在Lua中将多个字符串连接成为一个大字符串的话,可以通过如下方式实现,如:

1 local buff = ""
2 for line in io.lines() do
3 buff = buff .. line .. "\n"
4 end

上面的代码确实可以正常的完成工作,然而当行数较多时,这种方法将会导致大量的内存重新分配和内存间的数据拷贝,由此而带来的性能开销也是相当可观的。事实上,在很多编程语言中String都是不可变对象,如Java,因此如果通过该方式多次连接较大字符串时,均会导致同样的性能问题。为了解决该问题,Java中提供了StringBuilder类,而Lua中则可以利用table的concat方法来解决这一问题,见如下代码:

 
 1 local t = {}
2 for line in io.lines() do
3 t[#t + 1] = line .. "\n"
4 end
5 local s = table.concat(t)
6
7 --concat方法可以接受两个参数,因此上面的方式还可以改为:
8 local t = {}
9 for line in io.lines() do
10 t[#t + 1] = line
11 end
12 local s = table.concat(t,"\n")
 
 
 
 

Step By Step(Lua数据结构)的更多相关文章

  1. Step By Step(Lua基础知识)

    Step By Step(Lua基础知识) 一.基础知识:    1. 第一个程序和函数:    在目前这个学习阶段,运行Lua程序最好的方式就是通过Lua自带的解释器程序,如:    /> l ...

  2. Step By Step(Lua开篇)

    Step By Step(Lua开篇) 一.简介: Lua作为目前最为流行的.免费轻量级嵌入式脚本语言,在很多工业级的应用程序中被广泛应用,如Adobe's Photoshop,甚至是在一些著名的游戏 ...

  3. Step By Step(C调用Lua)

    Step By Step(C调用Lua) 1. 基础:    Lua的一项重要用途就是作为一种配置语言.现在从一个简单的示例开始吧.    --这里是用Lua代码定义的窗口大小的配置信息    wid ...

  4. Step By Step(Lua系统库)

    Step By Step(Lua系统库) Lua为了保证高度的可移植性,因此,它的标准库仅仅提供了非常少的功能,特别是和OS相关的库.但是Lua还提供了一些扩展库,比如Posix库等.对于文件操作而言 ...

  5. Step By Step(Lua输入输出库)

    Step By Step(Lua输入输出库) I/O库为文件操作提供了两种不同的模型,简单模型和完整模型.简单模型假设一个当前输入文件和一个当前输出文件,他的I/O操作均作用于这些文件.完整模型则使用 ...

  6. Step By Step(Lua字符串库)

    Step By Step(Lua字符串库) 1. 基础字符串函数:    字符串库中有一些函数非常简单,如:    1). string.len(s) 返回字符串s的长度:    2). string ...

  7. Step By Step(Lua弱引用table)

    Step By Step(Lua弱引用table) Lua采用了基于垃圾收集的内存管理机制,因此对于程序员来说,在很多时候内存问题都将不再困扰他们.然而任何垃圾收集器都不是万能的,在有些特殊情况下,垃 ...

  8. Step By Step(Lua面向对象)

    Step By Step(Lua面向对象) Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码: 1 Account = {balance = 0}2 function ...

  9. Step By Step(Lua模块与包)

    Step By Step(Lua模块与包) 从Lua 5.1开始,我们可以使用require和module函数来获取和创建Lua中的模块.从使用者的角度来看,一个模块就是一个程序库,可以通过requi ...

随机推荐

  1. Vue.js小案例、生命周期函数及axios的使用

    一.调色框小案例: 随着三个滑动框的变化,颜色框的颜色随之改变 1.1.实例代码 <!DOCTYPE html> <html lang="en" xmlns:v- ...

  2. 十步解决php utf-8编码

    以前说过如果JS文件不是UTF8会在IE有bug,所以JS代码也要用UTF-8.还有数据库也都要用UTF-8.php用UTF-8总结: php文件本身必须是UTF-8编码.不像Java会生成class ...

  3. drozer源码学习:app

    源码下载:https://github.com/mwrlabs/drozer:模块的源码位于src.drozer.modules,根据模块名来划分文件夹: app.auxiliary.exploit. ...

  4. 学习Canvas绘图与动画基础 制作弧和圆(五)

    1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="U ...

  5. mac打开class文件

    本来不想写这个东西的.但是这个却费了我一番周折. 我要先声明一点的是,我从来不讲iOS当成一个单独的系统,而是将这个操作系统归位unix内核的系统. 简单来说,我把它当成linux在用. 但是,mac ...

  6. 多变量高斯(MVN)概率建模的两种方案

    摘要:在我们的时序异常检测应用中,设计了对时序数据进行多变量高斯(MVN)建模的算法方案进行异常检测,本文对基于tensorflow的两种MVN建模方案进行了总结. 1.基于custom choles ...

  7. 用Taro写一个微信小程序(二)——配置目录别名

    配置别名可以方便书写代码引用路径,让代码更整洁. 官方文档可参考https://nervjs.github.io/taro/docs/config-detail#alias 一.在config/ind ...

  8. 有趣的css—简单的下雨效果

    简单的下雨效果 前言 最近在b站上看到一个下雨效果的视频,感觉思路很清奇,我也按照自己的思路做了一个简单的下雨效果. 由于我制作GIF图片的工具最多只支持制作33FPS的GIF图,所以看起来可能有一点 ...

  9. 利用实体bean对象批量数据传输处理

    利用实体bean对象批量数据传输处理 需求 现在有两方数据库表结构相同,一方A.另一个方B,现想从A处查询出多个表的数据,传输到B地保存起来. 解决方案1 最简单粗暴的方法就是,查询出A处相关表的数据 ...

  10. mysql枚举和集合

    create table consumer( id int, name char(16), sex enum('male','female','other'), level enum('vip1',' ...