递增整数序列模式识别与后续元素生成的JavaScript算法实现咨询
分享一个我之前实现的JavaScript解决方案,专门用来处理这类短递增序列的预测问题,尽可能覆盖常见的序列模式,还能根据输入长度自动筛选最靠谱的模式生成后续元素。
核心思路
因为输入是短序列,我们需要先枚举所有可能符合当前序列的数学模式,然后根据模式的“精确性”排序(比如需要更多输入项才能验证的模式,优先级更高,因为它的假设更具体),最后用优先级最高的模式生成后续10个元素。如果有多个等效优先级的模式,会同时生成多种可能的结果。
支持的常见序列模式
我实现了以下几种最常用的模式,覆盖大部分面试场景:
- 等差数列:所有相邻元素的差值相等(比如
4,14,24,差值10) - 线性递推序列:满足
current = a * previous + b,当序列长度≥3时可以解出唯一的a和b(比如4,14,34,符合current = 2*prev +6) - 斐波那契类序列:当前项等于前两项之和(比如
1,1,2,3,5) - 二级等差数列:相邻元素的差值构成等差数列(比如
1,3,6,10,差值为2,3,4) - 等比数列:所有相邻元素的比值相等(比如
2,4,8,16,比值2) - 平方/立方序列:每个元素是某个整数的平方或立方(比如
1,4,9,16是平方序列,1,8,27是立方序列)
JavaScript代码实现
// 解析输入字符串为整数数组 function parseInput(inputStr) { return inputStr.split(' ').map(Number).filter(num => !isNaN(num)); } // 检测等差数列:返回是否匹配,以及生成下一项的函数 function checkArithmetic(seq) { if (seq.length < 2) return { match: false }; const diff = seq[1] - seq[0]; for (let i = 2; i < seq.length; i++) { if (seq[i] - seq[i-1] !== diff) { return { match: false }; } } return { match: true, name: '等差数列', nextFn: (last) => last + diff }; } // 检测线性递推序列(current = a*prev + b) function checkLinearRecurrence(seq) { if (seq.length < 2) return { match: false }; // 序列长度为2时,返回两种常见的线性递推解 if (seq.length === 2) { const diff = seq[1] - seq[0]; return [ { match: true, name: `线性递推(${seq[1]} = 1*${seq[0]} + ${diff})`, nextFn: (last) => last + diff }, { match: true, name: `线性递推(${seq[1]} = 2*${seq[0]} + ${seq[1]-2*seq[0]})`, nextFn: (last) => 2 * last + (seq[1] - 2 * seq[0]) } ]; } // 序列长度≥3时,解方程组验证唯一的a和b const a = (seq[2] - seq[1]) / (seq[1] - seq[0]); if (!Number.isInteger(a)) return { match: false }; const b = seq[1] - a * seq[0]; for (let i = 2; i < seq.length; i++) { if (seq[i] !== a * seq[i-1] + b) { return { match: false }; } } return { match: true, name: `线性递推(current = ${a}*prev + ${b})`, nextFn: (last) => a * last + b }; } // 检测斐波那契类序列(当前项=前两项之和) function checkFibonacci(seq) { if (seq.length < 3) return { match: false }; for (let i = 2; i < seq.length; i++) { if (seq[i] !== seq[i-1] + seq[i-2]) { return { match: false }; } } return { match: true, name: '斐波那契类序列(前两项之和)', nextFn: (last, secondLast) => last + secondLast }; } // 检测二级等差数列 function checkSecondOrderArithmetic(seq) { if (seq.length < 3) return { match: false }; const diffs = []; for (let i = 1; i < seq.length; i++) { diffs.push(seq[i] - seq[i-1]); } const arithmeticCheck = checkArithmetic(diffs); if (!arithmeticCheck.match) return { match: false }; return { match: true, name: '二级等差数列', nextFn: (last) => { const lastDiff = diffs[diffs.length - 1]; const nextDiff = arithmeticCheck.nextFn(lastDiff); return last + nextDiff; } }; } // 检测等比数列 function checkGeometric(seq) { if (seq.length < 2) return { match: false }; const ratio = seq[1] / seq[0]; if (!Number.isInteger(ratio)) return { match: false }; for (let i = 2; i < seq.length; i++) { if (seq[i] / seq[i-1] !== ratio) { return { match: false }; } } return { match: true, name: `等比数列(比值${ratio})`, nextFn: (last) => last * ratio }; } // 检测平方/立方序列 function checkPowerSequence(seq) { const possiblePowers = []; // 检查平方序列 const squareRoots = seq.map(num => Math.sqrt(num)); if (squareRoots.every(root => Number.isInteger(root))) { const lastRoot = squareRoots[squareRoots.length - 1]; possiblePowers.push({ match: true, name: '平方序列', nextFn: () => (lastRoot + 1) ** 2 }); } // 检查立方序列 const cubeRoots = seq.map(num => Math.cbrt(num)); if (cubeRoots.every(root => Math.abs(root - Math.round(root)) < 1e-9)) { const lastRoot = Math.round(cubeRoots[cubeRoots.length - 1]); possiblePowers.push({ match: true, name: '立方序列', nextFn: () => (lastRoot + 1) ** 3 }); } return possiblePowers.length > 0 ? possiblePowers : { match: false }; } // 收集所有匹配的模式并去重 function getAllMatchingPatterns(seq) { const patterns = []; // 逐个检查每种模式 const arithmetic = checkArithmetic(seq); if (arithmetic.match) patterns.push(arithmetic); const linear = checkLinearRecurrence(seq); if (Array.isArray(linear)) { linear.filter(p => p.match).forEach(p => patterns.push(p)); } else if (linear.match) { patterns.push(linear); } const fibonacci = checkFibonacci(seq); if (fibonacci.match) patterns.push(fibonacci); const secondOrder = checkSecondOrderArithmetic(seq); if (secondOrder.match) patterns.push(secondOrder); const geometric = checkGeometric(seq); if (geometric.match) patterns.push(geometric); const power = checkPowerSequence(seq); if (Array.isArray(power)) { power.forEach(p => patterns.push(p)); } else if (power.match) { patterns.push(power); } // 去重避免重复模式 return Array.from(new Map(patterns.map(p => [p.name, p])).values()); } // 根据模式生成后续n个元素 function generateFromPattern(seq, pattern, count) { const result = [...seq]; for (let i = 0; i < count; i++) { let next; if (pattern.name.includes('斐波那契')) { next = pattern.nextFn(result[result.length-1], result[result.length-2]); } else { next = pattern.nextFn(result[result.length-1]); } result.push(next); } return result.slice(seq.length); } // 生成后续元素的主函数 function generateNextElements(seq, count = 10) { const patterns = getAllMatchingPatterns(seq); if (patterns.length === 0) { // 无匹配模式时,默认使用最后一个差值的等差模式 const diff = seq.length >=2 ? seq[seq.length-1] - seq[seq.length-2] : 1; const defaultPattern = { name: '默认等差模式', nextFn: (last) => last + diff }; return [{ patternName: defaultPattern.name, nextElements: generateFromPattern(seq, defaultPattern, count) }]; } // 按模式优先级排序:需要更多输入项的模式优先级更高 const priorityOrder = { '二级等差数列': 5, '斐波那契类序列(前两项之和)': 4, '线性递推(current = a*prev + b)': 3, '等比数列(比值a)': 2, '平方序列': 2, '立方序列': 2, '等差数列': 1, '默认等差模式': 0 }; patterns.sort((a, b) => (priorityOrder[b.name] || 0) - (priorityOrder[a.name] || 0)); // 提取所有最高优先级的模式 const highestPriority = priorityOrder[patterns[0].name] || 0; const topPatterns = patterns.filter(p => (priorityOrder[p.name] || 0) === highestPriority); return topPatterns.map(pattern => ({ patternName: pattern.name, nextElements: generateFromPattern(seq, pattern, count) })); } // 示例调用函数 function runExample(inputStr) { const seq = parseInput(inputStr); console.log(`输入序列: ${seq.join(', ')}`); const results = generateNextElements(seq); results.forEach(res => { console.log(`根据【${res.patternName}】生成的后续10个元素: ${res.nextElements.join(', ')}`); }); console.log('---'); } // 测试示例 runExample("4 14"); runExample("4 14 34"); runExample("1 1 2 3"); runExample("1 3 6 10"); runExample("2 4 8 16"); runExample("1 4 9 16");
测试结果说明
- 输入
4 14:会匹配等差数列和两种线性递推模式,生成两种可能的后续序列(24,34,44,...和34,74,154,...) - 输入
4 14 34:只有线性递推模式匹配(current=2*prev+6),生成74, 154, 314, 634, 1274, 2554, 5114, 10234, 20474, 40954 - 输入
1 1 2 3:匹配斐波那契类序列,生成5,8,13,21,34,55,89,144,233,377 - 输入
1 3 6 10:匹配二级等差数列,生成15,21,28,36,45,55,66,78,91,105
内容的提问来源于stack exchange,提问作者Development Flow




