我有两个包含数值的整数数组。我想查看两个列表并检查列表之间的共性(或缺少)。即我想遍历数组并查找出现在两个列表中的那些项目,而在一个单独的函数中,我想通过数组并查找第一个而不是第二个中的项目。
这样做的显而易见的方法是嵌套for循环:
var containedInFirst = false;
for (var primaryID = 0; primaryID < PrimaryArray.length; primaryID++) {
containedInFirst = false;
for (var secondaryID = 0; secondaryID < SecondaryArray.length; secondaryID++) {
if (PrimaryArray [primaryID] === SecondaryArray[secondaryID]) {
containedInFirst = true;
break;
}
}
//Do some more stuff based on the value of containedInFirst here
}
但是鉴于这些列表可能包含数百或数千条记录,这是相当多的迭代和处理器密集型。 因此,我想知道是否有更有效的方法来执行上述代码?不仅仅是实际的搜索,而是比Integer数组更有效的东西作为值的容器,或者只是不使用嵌套的for循环来遍历和比较内容。
有关更有效或更优雅的解决方案的任何想法?
答案 0 :(得分:31)
每个人都过于复杂。这是一个班轮:
var isEqual = (JSON.stringify(arr1.sort()) === JSON.stringify(arr2.sort()));
答案 1 :(得分:13)
首先对它们进行排序,然后并行地将它们淹没。
a.sort();
b.sort();
left = []; both = []; right = [];
i = 0; j = 0;
while (i < a.length && j < b.length) {
if (a[i] < b[j]) {
left.push(a[i]);
++i;
} else if (b[j] < a[i]) {
right.push(b[j]);
++j;
} else {
both.push(a[i]);
++i; ++j;
}
}
while (i < a.length) {
left.push(a[i]);
++i;
}
while (j < b.length) {
right.push(b[j]);
++j;
}
答案 2 :(得分:1)
当使用两个嵌套循环时,复杂度将为O(n * n)。 对两个数组进行排序可以在复杂度O(n log n)中完成。
AS Marcelo Cantos表示鸭蹒跚:) 通过并列中的两个都有复杂度O(n)导致O(n log n)+ O(n)的总体复杂度为O(n log n)。
答案 3 :(得分:0)
对两个数组进行排序,而不是循环一次并比较:
function diff(arrayToCompareTo, comparedArray)
{
Sort(arrayToCompareTo);
Sort(comparedArray);
var difference = [], same = [];
for(var i = 0; i < arrayToCompareTo.length; ++i)
{
if (arrayToCompareTo[i] != comparedArray[i])
difference.push(comparedArray[i]);
else
same.push(comparedArray[i]);
}
if (comparedArray.length > arrayToCompareTo.length)
for(var i = arrayToCompareTo.length; i < comparedArray.length; ++i)
difference.push(comparedArray[i]);
}
未经测试,如果出现问题,请告知我们
无论如何,这应该将你设置为正确的方向,因为它最好是O(N)而最差的是O(M)comparedArray.length > arrayToCompareTo.length
,它比O(N ^ 2)更有效。请注意,排序需要O(N log N)。
答案 4 :(得分:0)
我认为我的解决方案效率为O(N)(不需要排序),这里是:
var firstNotSecond;
function CompareIntArrays(arr1, arr2)
{
firstNotSecond = new Array();
var arr3 = new Array(); //appear in both
var arrTemp = new Array(); //used for firstNotSecond
var usedNumbers = new Array();
for (var i = 0; i < arr1.length; i++)
{
var key = arr1[i];
usedNumbers[key] = true;
arrTemp[key + ""] = true;
}
for (var i = 0; i < arr2.length; i++)
{
var key = arr2[i];
if (usedNumbers[key])
{
arr3[arr3.length] = key;
arrTemp[key] = false;
}
}
for (var key in arrTemp)
if (arrTemp[key])
firstNotSecond[firstNotSecond.length] = parseInt(key);
return arr3;
}
该函数将返回包含两个数组中存在的项的新数组,并将为全局数组分配第一个数组中存在的第二个数组中不存在的所有项。
此代码依赖于两个数组仅包含整数的事实。
用法示例:
alert(CompareIntArrays([15, 551, 25, 910, 11], [25, 11, 785, 880, 15]));
alert(firstNotSecond);
使用包含100,000个项目的数组进行测试:不到一秒钟。 使用每个包含200,000个项目的数组进行测试:不到2秒。
答案 5 :(得分:0)
另一种可能是在创建它们时对这些数组进行排序。我不确定你是否能做到这一点。但是,如果可以的话,它会增加一个元素添加到数组(O(log n)而不是O(1))的完整性,但它会将比较算法的复杂性降低到O(n)