local Set = {}
local mt = {}
function Set.new(l)
local set = {}
setmetatable(set,mt)
for _,v in ipairs(l) do
set[v] = true
end
return set
end
function Set.union(a,b)
if getmetatable(a) ~= mt or getmetatable(b)~=mt then
error("Attempt to 'add' a set with a non-set value",2)
end
local res = Set.new{}
for k in pairs(a) do res[k] = true end
for k in pairs(b) do res[k] = true end
return res
end
function Set.intersection(a,b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
function Set.tostring(set)
local l = {}
for e in pairs(set) do
l[#l+1] = e
end
return "{"..table.concat(l,",").."}"
end
function Set.print(s)
print(Set.tostring(s))
end
mt.__add = Set.union
mt.__mul = Set.intersection
mt.__le = function(a,b)
for k in pairs(a) do
if not b[k] then return false end
end
return true
end
--lua 内部代码排序转化调用
mt.__lt = function(a,b)
return a<=b and not(b<=a)
end
mt.__eq = function(a,b)
return a<=b and b<=a
end
s1 = Set.new{10,20,30,50}
s2 = Set.new{30,1}
print(getmetatable(s1))
print(getmetatable(s2))
s3 = s1+s2
Set.print(s3)
print(s1==s2*s1)
function basicSerialize(o)
if type(o) == "number" then
return tostring(o)
else --assume it is string
return string.format("%q",o)
end
end
function save (name,value,saved)
saved = saved or {} --init
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 --该table是否已保存过?
io.write(saved[value],"\n") --适用先前的名字
else
saved[value] = name ---为下使用保存名字
io.write("{}\n") ---创建一个新的table
for k,v in pairs(value) do
k = basicSerialize(k)
local fname = string.format("%s[%s]",name,k)
save(fname,v,saved)
end
end
else
error("cannot save a "..type(value))
end
end