当前位置 : 主页 > 网络编程 > lua >

lua流水账2:table

来源:互联网 收集:自由互联 发布时间:2021-06-23
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]
网友评论