数据序列模式识别优化:JavaScript控制图异常检测效率提升求助
优化后的实现方案
你的代码已经能正确运行,但可以从简化逻辑、提升性能两个维度进行优化,以下是两种更高效的实现方式:
基础优化版本(简洁高效)
移除不必要的事件发射器,直接统计窗口内"A"的数量,避免字符串拼接和正则匹配的开销:
const zones = ["C", "C", "A", "C", "C", "A", "B", "A", "C", "C", "C", "A", "A", "A", "A", "C"]; const results = { "test1": [], "test2": [] }; // 遍历所有有效窗口(连续3个元素) for (let i = 0; i <= zones.length - 3; i++) { let countA = 0; // 统计当前窗口内"A"的数量 for (let j = i; j < i + 3; j++) { if (zones[j] === "A") countA++; } // 符合条件则记录窗口索引 if (countA >= 2) { results.test1.push([i, i+1, i+2]); } } console.log(JSON.stringify(results, null, 2));
滑动窗口优化版本(大数据量友好)
当数组规模较大时,滑动窗口可以将时间复杂度从O(n*3)降到O(n),避免重复统计窗口内的元素:
const zones = ["C", "C", "A", "C", "C", "A", "B", "A", "C", "C", "C", "A", "A", "A", "A", "C"]; const results = { "test1": [], "test2": [] }; if (zones.length >= 3) { // 初始化第一个窗口的"A"数量 let countA = zones.slice(0, 3).filter(item => item === "A").length; if (countA >= 2) { results.test1.push([0, 1, 2]); } // 滑动窗口遍历剩余元素 for (let i = 1; i <= zones.length - 3; i++) { // 移出窗口左侧元素的计数 if (zones[i-1] === "A") countA--; // 加入窗口右侧新元素的计数 if (zones[i+2] === "A") countA++; if (countA >= 2) { results.test1.push([i, i+1, i+2]); } } } console.log(JSON.stringify(results, null, 2));
优化说明
- 移除EventEmitter:当前场景仅需收集结果,事件驱动增加了不必要的复杂度和运行开销,直接操作结果数组更高效。
- 避免字符串与正则操作:直接统计目标元素数量,比拼接字符串后用正则匹配减少了内存分配和正则解析的开销。
- 缩小循环范围:原代码遍历整个数组长度,实际上只需要遍历到
zones.length - 3,避免处理不足3个元素的无效窗口。 - 滑动窗口优化:通过复用前一个窗口的统计结果,仅更新窗口边界的元素计数,大幅减少重复计算,适合处理大规模数据。
内容的提问来源于stack exchange,提问作者kurt.kincaid
相关产品推荐
相关产品推荐

