如何将Lua中的table操作改写为长尾词?
- 内容介绍
- 相关推荐
本文共计1062个文字,预计阅读时间需要5分钟。
1. Lua中习惯上数组下标从1开始,Lua的标准库与此习惯保持一致。
2.链表的实现:`function CreateList(n) local list=nil for i=1, n do list={next=list, value=i} end return list end`
1.Lua中习惯上数组的下标从1开始,Lua的标准库与此习惯保持一致
2.链表的实现:
function CreateList(n) local list = nil; for i = 1,n do list = {next = list, value = i}; end return list; end function PrintList(list) local l = list; while l do print(l.value); l = l.next; end end PrintList(CreateList(10));
3.队列和双端队列的实现:
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; 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; list.last = last - 1; return value; end
4.集合和包
reserved = { ["while"] = true, ["end"] = true, ["function"] = true; ["local"] = true, } function allwords() local line = io.read(); local pos = 1; return function() while line do local s,e = string.find(line,"%w+",pos); if s then pos = e + 1; return string.sub(line,s,e); else line = io.read(); pos = 1; end end return nil; end end for w in allwords() do if reserved[w] then print("reserved have "..w); end end
5.字符串缓冲
Lua使用真正的垃圾收集算法,当它发现程序使用太多的内存,它就会遍历它所有的数据结构,去释放垃圾数据。一般情况下这个算法有很好的性能。但是由于Lua是字符串不可变的语言,下面的代码中会不断的产生新字符串,当旧字符串(垃圾数据)超过一定大小时,会导致Lua不断的进行垃圾回收。
local buff = ""; for line in io.line() do buff = buff..line.."\n"; end
优化方法
1:使用io.read(*all)一次性读入所有字符串
2:用一个栈,在栈的底部用来保存已经生成的大的字符串,而小的串从栈顶入栈。栈的状态变化和经典的汉诺塔问题类似:位于栈下面的串肯定要比上面的长,只要一个较长的串入栈后比它下面的串长,就将两个串合成一个新的更大的串,新生成的串继续与相邻的串比较,如果长于底部的将继续合并,循环进行到没有串可以合并或者到达栈底。
如下代码
function newStack() return {""} end function addString(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 ipairs({"this","is","a","test"}) do addString(s,line.."/n"); end
6.table转换为字符串:table.concat
local t = {"a","b","c"}; t = table.concat(t,":"); print(t); 输出:a:b:c
7.通过调用函数的形式处理数据
local authors = {}; function Entry(b) if b.author then authors[b.author] = true end end --函数调用,因为参数是table,所以可以省略() Entry{ author = "Donald E. Knuth", title = "Literate Programming", publisher = "CSLI", year = 1992 } Entry{ author = "Jon Bentley", title = "More Programming Pearls", publisher = "Addison-Wesley", year = 1990 } for name in pairs(authors) do print(name) end 输出:Donald E. Knuth Jon Bentley
8.os.execute()执行dos命令,返回系统状态码
9.序列化
function serialize(o) if type(o) == "number" then io.write(o); elseif type(o) == "string" then --%q可以使用双引号表示字符串并且可以正确处理包含引号和换行等 --特殊字符的字符串,可接受一个字符串并将其转化为可安全被Lua编译器 --读入的格式,比使用[[]]要安全,可避免出现"]]..os.execute('rm *')..[[出现的安全问题 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
function basicSerialize(o) if type(o) == "number" then return tostring(o); else return string.format("%q",o); end end function save(name,value,saved) saved = saved or {} io.write(name," = ") if type(value) == "number" or type(value) == "string" then io.write(basicSerialize(value),"\n"); elseif type(value) == "table" then if saved[value] then io.write(saved[value],"\n"); else saved[value] = name; io.write("{}\n"); for k,v in pairs(value) do local fieldname = string.format("%s[%s]",name,basicSerialize(k)); save(fieldname,v,saved); end end end end a = {x = 1,y = 2; {3,4,5}}; a[2] = a; a.z = a[1]; save('a',a); 输出: a = {} a[1] = {} a[1][1] = 3 a[1][2] = 4 a[1][3] = 5 a[2] = a a["y"] = 2 a["x"] = 1 a["z"] = a[1]
本文共计1062个文字,预计阅读时间需要5分钟。
1. Lua中习惯上数组下标从1开始,Lua的标准库与此习惯保持一致。
2.链表的实现:`function CreateList(n) local list=nil for i=1, n do list={next=list, value=i} end return list end`
1.Lua中习惯上数组的下标从1开始,Lua的标准库与此习惯保持一致
2.链表的实现:
function CreateList(n) local list = nil; for i = 1,n do list = {next = list, value = i}; end return list; end function PrintList(list) local l = list; while l do print(l.value); l = l.next; end end PrintList(CreateList(10));
3.队列和双端队列的实现:
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; 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; list.last = last - 1; return value; end
4.集合和包
reserved = { ["while"] = true, ["end"] = true, ["function"] = true; ["local"] = true, } function allwords() local line = io.read(); local pos = 1; return function() while line do local s,e = string.find(line,"%w+",pos); if s then pos = e + 1; return string.sub(line,s,e); else line = io.read(); pos = 1; end end return nil; end end for w in allwords() do if reserved[w] then print("reserved have "..w); end end
5.字符串缓冲
Lua使用真正的垃圾收集算法,当它发现程序使用太多的内存,它就会遍历它所有的数据结构,去释放垃圾数据。一般情况下这个算法有很好的性能。但是由于Lua是字符串不可变的语言,下面的代码中会不断的产生新字符串,当旧字符串(垃圾数据)超过一定大小时,会导致Lua不断的进行垃圾回收。
local buff = ""; for line in io.line() do buff = buff..line.."\n"; end
优化方法
1:使用io.read(*all)一次性读入所有字符串
2:用一个栈,在栈的底部用来保存已经生成的大的字符串,而小的串从栈顶入栈。栈的状态变化和经典的汉诺塔问题类似:位于栈下面的串肯定要比上面的长,只要一个较长的串入栈后比它下面的串长,就将两个串合成一个新的更大的串,新生成的串继续与相邻的串比较,如果长于底部的将继续合并,循环进行到没有串可以合并或者到达栈底。
如下代码
function newStack() return {""} end function addString(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 ipairs({"this","is","a","test"}) do addString(s,line.."/n"); end
6.table转换为字符串:table.concat
local t = {"a","b","c"}; t = table.concat(t,":"); print(t); 输出:a:b:c
7.通过调用函数的形式处理数据
local authors = {}; function Entry(b) if b.author then authors[b.author] = true end end --函数调用,因为参数是table,所以可以省略() Entry{ author = "Donald E. Knuth", title = "Literate Programming", publisher = "CSLI", year = 1992 } Entry{ author = "Jon Bentley", title = "More Programming Pearls", publisher = "Addison-Wesley", year = 1990 } for name in pairs(authors) do print(name) end 输出:Donald E. Knuth Jon Bentley
8.os.execute()执行dos命令,返回系统状态码
9.序列化
function serialize(o) if type(o) == "number" then io.write(o); elseif type(o) == "string" then --%q可以使用双引号表示字符串并且可以正确处理包含引号和换行等 --特殊字符的字符串,可接受一个字符串并将其转化为可安全被Lua编译器 --读入的格式,比使用[[]]要安全,可避免出现"]]..os.execute('rm *')..[[出现的安全问题 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
function basicSerialize(o) if type(o) == "number" then return tostring(o); else return string.format("%q",o); end end function save(name,value,saved) saved = saved or {} io.write(name," = ") if type(value) == "number" or type(value) == "string" then io.write(basicSerialize(value),"\n"); elseif type(value) == "table" then if saved[value] then io.write(saved[value],"\n"); else saved[value] = name; io.write("{}\n"); for k,v in pairs(value) do local fieldname = string.format("%s[%s]",name,basicSerialize(k)); save(fieldname,v,saved); end end end end a = {x = 1,y = 2; {3,4,5}}; a[2] = a; a.z = a[1]; save('a',a); 输出: a = {} a[1] = {} a[1][1] = 3 a[1][2] = 4 a[1][3] = 5 a[2] = a a["y"] = 2 a["x"] = 1 a["z"] = a[1]

