我写了一个脚本,而不是给出一组数据的真实平均值,而是返回包含大多数数据点的窗口。让我展示一些代码:
time.tic()
var selectedAverage = 0;
var highestPointCount = 0;
for (var i = 1; (i*step) <= maxValue; i++) {
var dataPointCount = 0;
for (var j = 0; j < myArray.length; j++) {
if (myArray[j] >= minValue+(i-1)*step && myArray[j] <= minValue+i*step) {
dataPointCount++;
}
}
if (dataPointCount > highestPointCount) {
highestPointCount = dataPointCount;
selectedAverage = (minValue+(i-1)*step)+Math.round(0.5*step);
}
}
console.log(time.toct().ms)
return selectedAverage;
首先,通过从最大值中减去最小值然后再确定10来计算步长值。因此,存在10个“水平”窗口。然后脚本计算每个窗口中的数据点数量并返回适当的平均值。
然而,当传入较大数字的数组(例如1.000.000)时,脚本似乎极度减速(有时超过200次)。数组长度大约为200但总长度相同,因此必须与实际值相关联。知道哪里出错了?
编辑: 获取步长值的代码:
var minValue = myArray.min();
var maxValue = myArray.max();
var step = Math.round((maxValue-minValue)/10);
if (step === 0) {
step = 1
}
.min()和.max()是附加到Array的原型。但这一切都非常快。我已经测量了每一步,它是for循环减速。
答案 0 :(得分:1)
我认为你的问题有两个不同的地方:
在嵌套代码中,您每次都会minValue+(i-1)*step
和minValue+i*step
计算相同的minValue
,i
和step
值。
你应该在第二个for循环之前把它拉起来:
var dataPointCount = 0;
var lowerLimit = minValue+(i-1)*step;
var higherLimit = minValue+1*step;
for (var j = 0; j < myArray.length; j++) {
if (myArray[j] >= lowerLimit && myArray[j] <= higherLimit) {
dataPointCount++;
}
}
答案 1 :(得分:1)
如果我正确理解你的算法,这应该删除所有不必要的计算并且要快得多:
var arr = [];
var maxQty=0;
var wantedAverage = 0;
for (var j = 0; j < 11; j++) {
arr[j]=0;
}
for (var j = 0; j < myArray.length; j++) {
var stepIndex = Math.floor((myArray[j]-minValue)/step)
arr[stepIndex]+=1;
if(arr[stepIndex] > maxQty ){
wantedAverage = minValue + stepIndex*step +Math.round(0.5*step);
maxQty = arr[stepIndex]
}
}
console.log(maxQty, wantedAverage)
我们只迭代数组的每个元素一次,并计算它所属的窗口的索引,向数量数组添加一个。然后,如果我们在找到的窗口中有更多的点数,我们会更新wantedAverage