我需要排序和删除顶点,我使用了这个东西。但最近我意识到这种方法很慢。
function Face(v1, v2, v3) {
var df = Math.hypot(v2[0] * 1 - v3[0] * 1, v2[1] * 1 - v3[1] * 1, v2[2] * 1 - v3[2] * 1);
if (df != 0) {
for (var dp = 0; dp < df; dp += gap) {
x = v3[0] * 1 + (v2[0] * 1 - v3[0] * 1) / df * dp;
y = v3[1] * 1 + (v2[1] * 1 - v3[1] * 1) / df * dp;
z = v3[2] * 1 + (v2[2] * 1 - v3[2] * 1) / df * dp;
var ds = Math.hypot(x - v1[0] * 1, y - v1[1] * 1, z - v1[2] * 1);
if (ds != 0) {
for (var dps = 0; dps < ds; dps += gap) {
fx = v1[0] * 1 + (x - v1[0] * 1) / ds * dps;
fy = v1[1] * 1 + (y - v1[1] * 1) / ds * dps;
fz = v1[2] * 1 + (z - v1[2] * 1) / ds * dps;
var ffx = Math.round(fx / gap) * gap;
var ffy = Math.round(fy / gap) * gap;
var ffz = Math.round(fz / gap) * gap;
if (check) {
if (!(findOne(output, [ffx, ffy, ffz]))) {
output.push([ffx, ffy, ffz]);
}
} else {
output.push([ffx, ffy, ffz]);
}
}
}
}
}
}
脸部(vertex1,vertex2,vertex3); 没有检查,更快。 (此方法调用几乎1000~10000次)
findOne(arr,[1,2]);//returns true. (I NEED THIS)
arr.includes([1,2]);//returns false.
arr[0]==[1,2];// returns false.
function findOne(arr, arr2) {
for(var l=0;l<arr.length;l++){
if(arr[l][0]==arr2[0]&&arr[l][1]==arr2[1]&&arr[l][2]==arr2[2]){
return true;
}
}
return false;
}
我尝试使用arr0.include(arr1),但如果param是数组,这不起作用。 如果(arr0 == arr1)也没有用。
有谁知道解决方案?
答案 0 :(得分:0)
你的解决方案不应该“非常慢”,它具有线性时间复杂性。你可以像这样检查O(1):
var lookup = {
'1#2': true,
'3#4': true
};
var arr = [[1, 2], [3, 4]];
function findOne(arr2) {
return lookup[arr2.join('#')];
}
function addArray(arrayToAdd) {
const s = arrayToAdd.join('#');
lookup[s] = true;
arr.push(arrayToAdd);
}
function removeAtIndex(index) {
const s = arr[index].join('#');
delete lookup[s];
arr.splice(index, 1);
}
想法是保持数组arr包含的查找表。显然,这需要您在每次添加或删除项目时更新查找表,我已提供了示例。这显然会占用更多的内存,我不确定你的数组有多大,所以不确定这是不是一个问题。
查找表还假设数组项是数字,如果它们是字符串,例如,['a。','ab']。join('。')和['a','。ab' ] .join('。')会产生不需要的相同字符串,请考虑到这一点。
既然你说你多次调用它,那么可能是我们应该优化的代码。如果你想检查10k项目是否在arr中,你当前在整个阵列上迭代10000 * arraySize次,而只需一次即可。
答案 1 :(得分:0)
此处有三种可能的用例,但您尚未指定您使用的用例,因此我将同时提及这两种情况。
一个例子:
var arr = [[1,2,3],[3,4,5]];
var arr2 = [3, 4, 5];
function buildMap(arr) {
var retObj = {};
for (var l=0;l<arr.length;l++) {
retObj[arr[l][0]] = {};
retObj[arr[l][0]][arr[l][1]] = {};
retObj[arr[l][0]][arr[l][1]][arr[l][2]] = true;
}
return retObj;
}
function findOne(mapArr, arr2) {
return mapArr[arr2[0]][arr2[1]][arr2[2]];
}
var mapArr = buildMap(arr);
console.log(findOne(mapArr, arr2));
案例2:Array1更改,Array2始终相同。你可以做同样的事情,切换两个阵列。
案例3:两个阵列都发生了变化。在这种情况下你不能做太多事情,你必须至少经过主阵列一次,所以你不能低于O(n)。除非你有其他一些你没有提到的约束(我特意想到的数据是否被排序)。
答案 2 :(得分:-2)
您可以将array#some
与array#every
一起使用。首先遍历每个数组,然后比较两个数组的长度,只有它们相等才比较每个数组。
var arr = [[1,2],[3,4]];
var findOne = (matrix, arr) => {
return matrix.some(a => a.length === arr.length && a.every((v,i) => v === arr[i]));
}
console.log(findOne(arr,[1,2]))
&#13;