3 回答
TA贡献1830条经验 获得超9个赞
这是一个查找样本数组中所有峰值的函数:
const chart = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141]
const findPeaks = chart => chart.reduce((agg, current, i) => {
const prev = chart[i - 1];
const next = chart[i + 1];
return current > prev && current > next ? [...agg, current] : agg;
}, []);
const peaks = findPeaks(chart);
console.log('peaks', peaks);
这记录: [1301, 1380, 2462, 2456, 1532, 2407, 2392, 1537, 2214, 1383]
这与您的问题的预期输出不匹配,但它确实对“峰值是什么”给出了准确的答案。
在这种情况下,“峰值”被定义为任何前任和后继都低于自身的数字。即 [1, 100, 1] 给出 100。 [1, 2, 3, 100, 3, 2, 100, 1] 给出 [100, 100]
更新
根据您的反馈,这里有一个函数,它需要一个峰的每边距离为 2 。结果仍然与您的问题不同,但这符合新表达的标准:
const findPeaks = chart => chart.reduce((agg, current, i) => {
const twoBack = chart[i - 2];
const prev = chart[i - 1];
const next = chart[i + 1];
const twoForward = chart[i + 2];
return (twoBack < prev && prev < current) && (current > next && next > twoForward )
? [...agg, current]
: agg;
}, []);
对于上述输入,这会产生:
[2462, 2456, 1532, 1537, 1383]
更新 2
这是找到所有峰值、计算出中值并返回大于中值的所有峰值的代码版本。这是与您在问题中要求的最接近的结果:
const findPeaks = chart => {
const peaks = chart.reduce((agg, current, i) => {
const twoBack = chart[i - 2];
const prev = chart[i - 1];
const next = chart[i + 1];
const twoForward = chart[i + 2];
return (prev < current) && (current > next)
? [...agg, current]
: agg;
}, []);
const mean = peaks.reduce((a, b) => a + b) / peaks.length;
return peaks.filter(peak => peak > mean);
}
这个的输出是:
[2462, 2456, 2407, 2392, 2214]
TA贡献1836条经验 获得超4个赞
没有更精确地定义所需的输出(例如,什么被认为是一个组?),这是一个简单的算法:
1) 将数组拆分为“低”和“高”序列。
例如[1, 10000, 100, 101, 20000, 20050, 30, 10, 2]=> [1], [10000], [100, 101], [20000, 20050], [30, 10, 2]。
2) 返回每个高序列的最大值。
let peaks = arr => {
let isHigh = a => a >= 2000;
let isLow = a => !isHigh(a);
let groups = [];
while (arr.length && arr.some(isHigh)) {
arr.splice(0, arr.findIndex(isHigh));
groups.push(arr.splice(0, arr.findIndex(isLow)));
}
return groups.map(group => Math.max(...group));
};
const arr = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141];
console.log(peaks(arr));
const arr2 = [1365, 1324, 1013, 1220, 1259, 2204, 2212, 1938, 1882, 1545, 1236, 2090, 2614, 1949, 1307, 1628, 1780, 1263, 1184, 2184, 1411, 1306, 2010, 2057, 1339, 1624, 2480, 2575, 2425, 2617, 2479, 1929, 1805, 1869, 1341, 1104, 2195, 1661, 1174, 1447, 1761, 1362, 1430];
console.log(peaks(arr2));
TA贡献1831条经验 获得超4个赞
为什么不保持简单?
var arr = [1,6,4,3,9,11];
var peaks = arr.sort((a, b) => a - b).reverse();
输出为:[11, 9, 6, 4, 3, 1]
然后:
var top5 = peaks.slice(0,5);
结果是:[11, 9, 6, 4, 3]
或者你的数学的整个代码:
const peaks1 = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141];
const peaks2 = [1365, 1324, 1013, 1220, 1259, 2204, 2212, 1938, 1882, 1545, 1236, 2090, 2614, 1949, 1307, 1628, 1780, 1263, 1184, 2184, 1411, 1306, 2010, 2057, 1339, 1624, 2480, 2575, 2425, 2617, 2479, 1929, 1805, 1869, 1341, 1104, 2195, 1661, 1174, 1447, 1761, 1362, 1430];
const peaks = [peaks1, peaks2];
function getPeaks(arr){
let peaks = [];
for(let i=0;i<arr.length;i++){
let currPeak = arr[i].sort((a, b) => a - b).reverse().slice(0,1)[0];
peaks.push(currPeak);
}
return peaks.sort((a, b) => a - b).reverse();
}
let result = getPeaks(peaks);
结果应该是:[2617, 2462]
添加回答
举报