Arrays 阵列与已知子序列差分的有效算法?

Arrays 阵列与已知子序列差分的有效算法?,arrays,algorithm,language-agnostic,string-comparison,array-difference,Arrays,Algorithm,Language Agnostic,String Comparison,Array Difference,我将一个数组传递给一个库函数,该库函数返回一个数组,该数组是输入数组的子序列。也就是说,第一和第二数组的顺序相同,但是第二数组可能缺少第一数组的任意数量的元素。这两个阵列中都不会有重复项 然后,我想构建一个新数组,其中包含输入中的所有元素,但不包含在函数的输出中 出于某种原因,尽管这听起来很琐碎,但我还是不断出错,尤其是在数组的末尾 示例1(典型): 输入数组a: [ yyz, ltn, tse, uln, ist, gva, doh, hhn, vlc, ios, app, tlv, lcy

我将一个数组传递给一个库函数,该库函数返回一个数组,该数组是输入数组的子序列。也就是说,第一和第二数组的顺序相同,但是第二数组可能缺少第一数组的任意数量的元素。这两个阵列中都不会有重复项

然后,我想构建一个新数组,其中包含输入中的所有元素,但不包含在函数的输出中

出于某种原因,尽管这听起来很琐碎,但我还是不断出错,尤其是在数组的末尾

示例1(典型):

输入数组a:

[ yyz, ltn, tse, uln, ist, gva, doh, hhn, vlc, ios, app, tlv, lcy ]
[ usa ]
输入阵列b:

[ yyz, ltn, tse, uln, ist, gva, doh, hhn, vlc, tlv, lcy ]
[ ]
输出数组“diff”:

示例2(最小值,当差异位于字符串末尾时显示一些错误):

输入数组a:

[ yyz, ltn, tse, uln, ist, gva, doh, hhn, vlc, ios, app, tlv, lcy ]
[ usa ]
输入阵列b:

[ yyz, ltn, tse, uln, ist, gva, doh, hhn, vlc, tlv, lcy ]
[ ]
输出数组“diff”:


(我将在JavaScript/jQuery中实现它,但我更感兴趣的是伪代码中的通用算法,因为我实际上要处理对象数组。所以请注意,我正在寻找专门使用数组索引的算法,而不是像在C/C++中那样使用指针的算法。)在java中,如果我使用数组,我可能会这样做。您必须循环返回的所有对象,并且必须将它们与您发送的所有对象进行比较,这样在最坏的情况下,我相信您的复杂性为O(n^2),但是,您可能可以通过对发送的列表进行排序,并使用指针检查每个位置来改进这一点(但由于您不想使用指针,所以我将此示例省略),那么您可能可以在O(n)中比较这一点

如果我想从集合接口使用一些东西,那么这会简单得多,因为可以使用“myArray.contains()”方法

用列表代替

public void doYourJob(){
        List<Object> allObjects = new ArrayList<Object>(); //hold all original values
        List<Object>  recivedArray = yourBlackBox(allObjects); //send in the array an gets the smaller one
        List<Object>  missingArray = new ArrayList<Object>();
        for(Object inObj : allObjects){
            if(!recivedArray.contains(inObj))
                missingArray.add(inObj);
        }
    }
public void doYourJob(){
List allObjects=new ArrayList();//保留所有原始值
List recivedArray=yourBlackBox(allObjects);//在数组中发送并获取较小的数组
List missingaray=new ArrayList();
对于(对象inObj:allObjects){
如果(!recivedArray.contains(inObj))
missingaray.add(inObj);
}
}
由于第二个数组b是第一个数组a的一个子集,顺序相同,您可以并行遍历两个数组,比较当前值,如果a的当前值与b的当前值不同,则取a的当前值:


您的阵列上有保证的顺序吗?如果有,执行以下操作应该相对简单:

# our inputs are array1 and array2, array2 is the one with 0 or more missing elements
ix1 = 0
ix2 = 0
diff = new array
while ix2 < length(array2)
  while (ix1 < length(array1)) and (array1[ix1] != array2[ix2])
     add array1[ix1] to diff
     ix1 = ix1 + 1
  ix1 = ix1 + 1
  ix2 = ix2 + i

return diff

如果(且仅当)将元素添加到数组中是O(1)(如果每次填充结果数组时将其大小增加一倍,则至少是渐近O(1))的话,这两种方法都应该(大致)以O(n)的形式运行.

你能举一个这样的数组的例子吗?我没有收到你的最后一个请求。你描述的互补数组不是真的输出吗?输出是输入的一个子序列,所以输出的成员也是输入的成员,是输出的所有元素。@istrandjev:是的,我也意识到了这一点并删除了它。我是在调试过程中生成它的,但在实际工作的代码中它没有任何意义(-:Gumbo的答案是我一直在寻找的那种,有一个循环和两个索引,不像目前为止其他建议的答案有两个循环或转换为随机访问数据类型。如果第二个不是子序列(订单不同)事实上,对于第一个数组,我会首先将其转换为哈希/映射/字典/关联数组-但在有保证的子序列的情况下,效率会较低。现在在我的实际代码中测试它…数组已经有效排序,因为较短的数组被称为子序列。如果其中一个数组包含重复项,则可能不会,但我刚刚澄清了问题,说明当我意识到这一点也很重要时,两个数组中都不会有重复。当差异位于数组末尾时,这似乎也遇到了问题。我将向问题添加一个新的最小示例来测试这一点。@hippietrail你是对的。你需要使用第一个数组的其余部分a在比较循环之后。很好,现在可以了!作为一项挑战,您认为在较长的字符串上仅使用一个循环仍然是优雅的吗?直觉上,这似乎是可能的。@hippietrail是的,这是可能的。我认为优雅只取决于个人喜好。
# our inputs are array1 and array2, array2 is the one with 0 or more missing elements
ix1 = 0
ix2 = 0
diff = new array
while ix2 < length(array2)
  while (ix1 < length(array1)) and (array1[ix1] != array2[ix2])
     add array1[ix1] to diff
     ix1 = ix1 + 1
  ix1 = ix1 + 1
  ix2 = ix2 + i

return diff
hash = new hash
diff = new array

for each element in array1
  hash[element] = 1

for each element in array2
  hash[element] = hash[element] + 1

for each key in hash
  if hash[key] == 1
    add hash[key] to diff