我有两个数组,我想检查是否每个元素arr2
都在中arr1
。如果元素的值在中重复arr2
,则该元素的值必须arr1
相等。最好的方法是什么?
arr1 = [1, 2, 3, 4]
arr2 = [1, 2]
checkSuperbag(arr1, arr2)
> true //both 1 and 2 are in arr1
arr1 = [1, 2, 3, 4]
arr2 = [1, 2, 5]
checkSuperbag(arr1, arr2)
> false //5 is not in arr1
arr1 = [1, 2, 3]
arr2 = [1, 2, 3, 3]
checkSuperbag(arr1, arr2)
> false //3 is not in arr1 twice
一种选择是对两个数组进行排序,然后遍历两个数组,然后比较元素。如果在超级袋中未找到子袋候选中的元素,则前者不是子袋。排序通常为O(n *log(n)),比较为O(max(s,t)),其中 s 和_t_是数组大小,总时间复杂度为O(m * log(m)) ,其中m =max(s,t)。
function superbag(sup, sub) {
sup.sort();
sub.sort();
var i, j;
for (i=0,j=0; i<sup.length && j<sub.length;) {
if (sup[i] < sub[j]) {
++i;
} else if (sup[i] == sub[j]) {
++i; ++j;
} else {
// sub[j] not in sup, so sub not subbag
return false;
}
}
// make sure there are no elements left in sub
return j == sub.length;
}
如果实际代码中的元素是整数,则可以使用特殊的整数排序算法(例如radixsort)来解决总体O(max(s,t))时间复杂度,尽管如果包很小,则构建-in的Array.sort
运行速度可能会比自定义整数排序快。
一种可能具有较小的时间复杂性的解决方案是创建一个袋类型。整数袋特别容易。翻转袋子的现有数组:创建一个对象或一个以整数为键并重复计数值的数组。因此不会浪费空间。您可以将行李操作用于子行李或超级行李检查。例如,从次要候选者中减去上级,然后测试结果是否为空。或者,contains
操作应为O(1)(或可能为O(log(n))),因此循环遍历子袋候选物并测试超级袋容纳量是否超过每个子袋元素的子袋容纳量应该是O(n)或O(n* log(n))。
以下未经测试。执行isInt
左为练习。
function IntBag(from) {
if (from instanceof IntBag) {
return from.clone();
} else if (from instanceof Array) {
for (var i=0; i < from.length) {
this.add(from[i]);
}
} else if (from) {
for (p in from) {
/* don't test from.hasOwnProperty(p); all that matters
is that p and from[p] are ints
*/
if (isInt(p) && isInt(from[p])) {
this.add(p, from[p]);
}
}
}
}
IntBag.prototype=[];
IntBag.prototype.size=0;
IntBag.prototype.clone = function() {
var clone = new IntBag();
this.each(function(i, count) {
clone.add(i, count);
});
return clone;
};
IntBag.prototype.contains = function(i) {
if (i in this) {
return this[i];
}
return 0;
};
IntBag.prototype.add = function(i, count) {
if (!count) {
count = 1;
}
if (i in this) {
this[i] += count;
} else {
this[i] = count;
}
this.size += count;
};
IntBag.prototype.remove = function(i, count) {
if (! i in this) {
return;
}
if (!count) {
count = 1;
}
this[i] -= count;
if (this[i] > 0) {
// element is still in bag
this.size -= count;
} else {
// remove element entirely
this.size -= count + this[i];
delete this[i];
}
};
IntBag.prototype.each = function(f) {
var i;
foreach (i in this) {
f(i, this[i]);
}
};
IntBag.prototype.find = function(p) {
var result = [];
var i;
foreach (i in this.elements) {
if (p(i, this[i])) {
return i;
}
}
return null;
};
IntBag.prototype.sub = function(other) {
other.each(function(i, count) {
this.remove(i, count);
});
return this;
};
IntBag.prototype.union = function(other) {
var union = this.clone();
other.each(function(i, count) {
if (union.contains(i) < count) {
union.add(i, count - union.contains(i));
}
});
return union;
};
IntBag.prototype.intersect = function(other) {
var intersection = new IntBag();
this.each(function (i, count) {
if (other.contains(i)) {
intersection.add(i, Math.min(count, other.contains(i)));
}
});
return intersection;
};
IntBag.prototype.diff = function(other) {
var mine = this.clone();
mine.sub(other);
var others = other.clone();
others.sub(this);
mine.union(others);
return mine;
};
IntBag.prototype.subbag = function(super) {
return this.size <= super.size
&& null !== this.find(
function (i, count) {
return super.contains(i) < this.contains(i);
}));
};
问题内容: 我在PHP中有两个数组,如下所示: 人: 通缉犯: 如何检查是否 所有 的的 人们 元素是在 通缉犯 阵列? 在此示例中,它应该返回,因为在 通缉犯中 。 问题答案: 您可以使用。
假设我有两个数组,和,其中是的子集: 我想返回如下数组: 如果只是一个数字,那就足够简单了(),但我尝试了y中的等效
我如何在JavaScript中做到这一点?
问题内容: 我想比较两个双打数组。使用香草JUnit,我可以执行以下操作: 我想知道如何使用Hamcrest做到这一点,最好不要创建自定义Matchers(如果可能)。类似于对数组中的每个元素使用“关闭”匹配器。 问题答案: 如果更改为a,则可以使用以下辅助方法: 您也可以使用原始数组来完成此操作,但是您将需要一个自定义匹配器。
问题内容: 我试图遍历2个数组,外部数组则比另一个数组更长。它将循环遍历第一个,如果第二个数组不包含该int,它将返回false。但是我不知道该怎么做。这是我到目前为止所拥有的: 运行时出现此错误: 我想知道是否可以不使用嵌套循环(如上)来完成。我知道我做错了,如果有人可以在此问题上提供帮助,那就太好了。我也不确定要在Java文档中寻找什么类。 问题答案: 您可以检查较大的数组是否包含较小数组中的
我想比较两个数组的双打。使用香草JUnit,我可以: