从代码清洁性或效率方面,找到两个Lua编号表(即仅包含两个表中都存在的值的表)的“交集”的最佳方法是什么?
例如,我有
a={1,2,3,4,5}
b={3,4,5,6,7}
由于在a
和b
中都找到了3、4和5,所以我要{3,4,5}
。
答案 0 :(得分:0)
您需要在其中一个表上iterate
,如果在另一个表中找到,则output the value
。在我的计算机上,以下代码返回{3,4,5},它基本上实现了intersection of 2 sets
。
a={1,2,3,4,5}
b={3,4,5,6,7}
function Contains (Array, Item)
local Found = false
local Index = 1
while ((not Found) and (Index <= #Array)) do
if Array[Index] == Item then
Found = true
else
Index = Index + 1
end
end
return Found
end
function Intersects (Ta, Tb)
local Result = { }
local Index
for Index = 1, #Tb do
if Contains(Ta, Tb[Index]) then
Result[#Result + 1] = Tb[Index]
end
end
return Result
end
Result = Intersects(a, b)
-- Print the results
local Index, Value
for Index, Value in ipairs(Result) do
print(Value)
end
答案 1 :(得分:0)
我建议基于 sets 的方法稍有不同。性能并不一定会提高,代码会干净,可理解且可扩展。
在Lua中,一个集合可以很容易地实现为一个表,其中键是集合项,值是true
,因此,要检查集合中是否存在某个项,您只需要{{1 }}。
我将给出代码的三个变体。首先干净地实现了一个相交运算符,但随后必须将结果集转换回索引的Lua表。第二个立即返回两个集合的交集作为数组。第三是前两者之间的折衷。
请注意,它们都不包含在if set[item] then
和a
上的嵌套循环:它是 O(a + b)而不是 O(ab)。
第一:
b
第二:
local insert, sort = table.insert, table.sort -- localise for performance.
local a = {1,2,3,4,5}
local b = {3,4,5,6,7}
local function toset (tbl)
local set = {}
for _, value in ipairs (tbl) do
set [value] = true
end
return set
end
local function intersect (set1, set2)
local intersection = {}
for item, _ in pairs (set1) do
if set2 [item] then
intersection [item] = true
end
end
return intersection
end
local function toarray (set)
local array = {}
for item, _ in pairs (set) do
insert (array, item)
end
sort (array) -- since you want {3,4,5} not {4,5,3}
return array
end
-- Fortunately, table.concat does not require previous tostring:
print ('{' .. table.concat (toarray (intersect (toset (a), toset (b))), ', ') .. '}')
第三:
local insert, sort = table.insert, table.sort -- localise for performance.
local a = {1,2,3,4,5}
local b = {3,4,5,6,7}
local function toset (tbl)
local set = {}
for _, value in ipairs (tbl) do
set [value] = true
end
return set
end
local function intersect_and_to_array (set1, set2)
local array = {}
for item, _ in pairs (set1) do
if set2 [item] then
insert (array, item)
end
end
sort (array) -- since you want {3,4,5} not {4,5,3}
return array
end
-- Fortunately, table.concat does not require previous tostring:
print ('{' .. table.concat (intersect_and_to_array (toset (a), toset (b)), ', ') .. '}')