标签:
Lua中的table不是一种简单的数据结构,它可以作为其它数据结构的基础。如数组array、记录record、线性表list、队列queue和集合set等,在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} print("The length of array 'a' is " .. #squares)在Lua中习惯上数组的下表从1开始,Lua的标准库与此习惯保持一致,因此如果你的数组下标也是从1开始你就可以直接使用标准库的函数,否则就无法直接使用。
local list = nil for i = 1, 10 do list = { next = list ,value = i} end local l = list while l do print(l.value) l = l.next end
其他类型的链表,像双向链表和循环链表类似的也是很容易实现的。然后在Lua中在很少情况下才需要这些数据结构,因为通常情况下有更简单的方式来替换链表。比如,我们可以用一个非常大的数组来表示栈,其中一个域n指向栈顶。
下面,我们可以在常量时间内,完成在队列的两端进行插入和删除操作了。
local List = {} function List.new () return {first = 0, last = -1} end function List.pushleft (list, value) local first = list.first - 1 list.first = first list[first] = value end function List.pushright (list, value) local last = list.last + 1 list.last = last list[last] = value end function List.popleft (list) local first = list.first if first > list.last then error("list is empty") end local value = list[first] list[first] = nil -- to allow garbage collection list.first = first + 1 return value end function List.popright (list) local last = list.last if list.first > last then error("list is empty") end local value = list[last] list[last] = nil -- to allow garbage collection list.last = last - 1 return value end对严格意义上的队列来讲,我们只能调用pushright和popleft,这样以来,first和last的索引值都随之增加,幸运的是我们使用的是Lua的table实现的,你可以访问数组的元素,通过使用下标从1到20,也可以16,777,216 到 16,777,236。
reserved = {["while"] = true, ["end"] = true,["function"] = true, ["local"] = true,} for w in allwords() do if reserved[w] then -- `w' is a reserved word end end --还可以使用辅助函数更加清晰的构造集合: function Set (list) local set = {} for _, l in ipairs(list) do set[l] = true end return set end reserved = Set{"while", "end", "function", "local", }说明:集合的元素是table的键,而不是值。原始集合是:{"while", "end", "function", "local", }
在Lua中我们可以将包(Bag)看成MultiSet,与普通集合不同的是该容器中允许key相同的元素在容器中多次出现。下面的代码通过为table中的元素添加计数器的方式来模拟实现该数据结构,如:
function insert(bag, element) bag[element] = (bag[element] or 0) + 1 end function remove(bag, element) local count = bag[element] bag[element] = (count and count > 1) and count - 1 or nil end
local buff = "" for line in io.lines() do buff = buff .. line .. "\n" end上面的代码确实可以正常的完成工作,然而当行数较多时,这种方法将会导致大量的内存重新分配和内存间的数据拷贝,由此而带来的性能开销也是相当可观的。事实上,在很多编程语言中String都是不可变对象,如Java,因此如果通过该方式多次连接较大字符串时,均会导致同样的性能问题。为了解决该问题,Java中提供了StringBuilder类,而Lua中则可以利用table的concat方法来解决这一问题,见如下代码:
local t = {} for line in io.lines() do t[#t + 1] = line .. "\n" end local s = table.concat(t) --concat方法可以接受两个参数,因此上面的方式还可以改为: local t = {} for line in io.lines() do t[#t + 1] = line end local s = table.concat(t,"\n")
标签:
原文地址:http://blog.csdn.net/shimazhuge/article/details/42212725