我有一个数组数组。内部阵列是16个插槽,每个插槽的编号为0..15。一个简单的排列。
我想检查外部数组中包含的任何数组是否具有相同的值 测试数组(16个值的排列)。
我可以通过类似的方式轻松地做到这一点:
var containsArray = function (outer, inner) {
var len = inner.length;
for (var i=0; i<outer.length; i++) {
var n = outer[i];
var equal = true;
for (var x=0; x<len; x++) {
if (n[x] != inner[x]) {
equal = false;
break;
}
}
if (equal) return true;
}
return false;
}
但有更快的方法吗?
我可以为每个排列分配一个整数值 - 实际上是64位整数吗?
插槽中的每个值都是0..15,这意味着它可以用4位表示。有16个插槽,这意味着64位信息。
在C#中,使用Int64类型使用这种方法计算和存储内部数组(或置换)的散列很容易。 Javascript是否有64位整数数学可以使这个快速?
答案 0 :(得分:0)
这个速度和它一样快,比较javascript中的数组(和其他语言一样)是非常痛苦的。我假设在进行内循环之前比较长度不能获得任何速度优势,因为你的数组是固定大小的?
我认为只有“优化”才能简化语法,但它不会给你任何速度优势。你已尽可能早地回来了。
你使用64位整数的建议听起来很有意思,但是由于javascript没有Int64类型(据我所知),这需要更复杂的东西,实际上可能比你当前的方法更慢。 / p>
答案 1 :(得分:0)
如何比较myInnerArray.join('##') == myCompareArray.join('##');
的字符串值(当然后一个连接应该进行一次并存储在变量中,而不是像每次迭代那样)。
我不知道实际的性能差异是什么,但代码会更简洁。如果你正在进行很多次的比较,你可以将这些值保存在某个地方,并且比较可能会更快,至少第二次。
这里明显的问题是比较容易出现误报,请考虑
var array1 = ["a", "b"];
var array2 = ["a##b"];
但是如果你能够很好地依赖你的数据,你可能会忽视它?否则,如果您始终比较连接结果和的长度,则不会出现问题。
答案 2 :(得分:0)
您是否真的在外部数组中寻找特定的数组实例?也就是说,如果inner
匹配,它是否会与匹配的嵌套数组共享相同的引用?如果是这样,您可以跳过内部比较循环,只需执行此操作:
var containsArray = function (outer, inner) {
var len = inner.length;
for (var i=0; i<outer.length; i++) {
if (outer[i] === inner) return true;
}
return false;
}
如果你不能这样做,你仍然可以通过在每次循环迭代中不引用.length字段来取得一些进展 - 这是一个昂贵的引用,因为每次引用时都会重新计算长度。
var containsArray = function (outer, inner) {
var innerLen = inner.length, outerLen = outer.length;
for (var i=0; i<outerLen; i++) {
var n = outer[i];
var equal = true;
for (var x=0; x<innerLen; x++) {
if (n[x] != inner[x]) {
equal = false;
}
}
if (equal) return true;
}
return false;
}
此外,我已经看到声称这种形式的循环更快,但我没有看到它产生可衡量的差异的情况:
var i = 0;
while (i++ < outerLen) {
//...
}
编辑:不,请勿删除equal
变量;这对我来说是一个坏主意。
答案 3 :(得分:0)
唯一的想法是将循环推入实现并交换一些内存(推测,你必须测试假设)速度增益,这也依赖于非可移植的Array.prototype.{toSource,map}
:
var to_str = function (a) {
a.sort();
return a.toSource();
}
var containsString = function (outer, inner) {
var len = outer.length;
for (var i=0; i<len; ++i) {
if (outer[i] == inner)
return true;
}
return false;
}
var found = containsString(
outer.map(to_str)
, to_str(inner)
);
答案 4 :(得分:0)
var containsArray = function (outer, inner) {
var innerLen = inner.length,
innerLast = inner.length-1,
outerLen = outer.length;
outerLoop: for (var i=0; i<outerLen; i++) {
var n = outer[i];
for (var x = 0; x < innerLen; x++) {
if (n[x] != inner[x]) {
continue outerLoop;
}
if (x == innerLast) return true;
}
}
return false;
}
答案 5 :(得分:0)
Knuth-Morris-Pratt算法
Rumtime:O(n),n =干草堆的大小
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm