问题描述
首先使用伪代码:
local array = {
"a","b","c","d","e","f","g",}
现在,创建一些数据,该数据存储有关原始阵列的重要信息。可能只是复制整个数组,但由于我不知道解决问题的最快方法是什么,所以我将其保留。
local info = createinfo(array)
现在使用table.remove/insert()
创建该数组的新版本,或者仅使用原始元素创建一个新数组。因此,没有覆盖table.insert/remove()
的恶作剧。
local array = {
"a",}
找出发生了什么变化(以下说明)
local changes = calculatechanges(array,info)
我想知道什么?
- 已移动了哪些元素? (例如
"c"
) - 已删除什么元素? (例如
"g"
) - 我对元素已移到哪里不感兴趣。
如果有可能的话,我怎么发现呢?
既然我最初的问题是时间紧迫的(createchanges()
和calculatechanges()
),那么最快的方法是什么?
P.S。顺便说一句,如果那很重要,我正在使用Lua 5.1。
编辑: 作为“更改”,我定义以下内容: 将原始数组转换为修改版本的“将x从索引i移至j”的最小数量是多少?
另一个编辑: 可能我正在寻找Levenshtein距离的类似实现。但是,我需要知道哪些元素必须替换,而不是(仅)距离。
解决方法
这是一个解决方案,我反转了数组以简化索引查找。
然后,我使用while循环来选择性地递增a1
或a2
的索引。
function diff(a1,a2)
local added = {}
local moved = {}
local removed = {}
local a1IndexOf = {}
for i,v in ipairs(a1)do
a1IndexOf[v] = i
end
local a2IndexOf = {}
for i,v in ipairs(a2)do
a2IndexOf[v] = i
end
local index1 = 1
local index2 = 1
while(index1 <= #a1) do
local value1 = a1[index1]
local value2 = a2[index2]
if value1 == value2 then
index1 = index1 + 1
index2 = index2 + 1
elseif a2IndexOf[value1] == nil then
removed[value1] = true
index1 = index1 + 1
elseif moved[value1] then
index1 = index1 + 1
elseif moved[value2] then
index2 = index2 + 1
elseif a1IndexOf[value2] < a2IndexOf[value1] then
moved[value1] = true
index1 = index1 + 1
else
moved[value2] = true
index2 = index2 + 1
end
end
print("\nElements Moved:")
for v in pairs(moved) do
print("\t" .. v)
end
print("\nElements Removed:")
for v in pairs(removed) do
print("\t" .. v)
end
end
一些示例输入和结果:
local array = {
"a","b","c",}
local info = {
"a",}
Elements Moved:
c
Elements Removed:
local array = {
"a",}
Elements Moved:
Elements Removed:
b