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 (li
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]