当前位置:首页 > JavaScript

js实现组合

2026-02-01 08:45:56JavaScript

组合问题的基本概念

组合是指从一组元素中选出若干个元素,不考虑顺序。例如从数组 [1, 2, 3] 中选出 2 个元素,可能的组合为 [1,2], [1,3], [2,3]

递归实现组合

递归是解决组合问题的经典方法,通过逐步缩小问题规模并合并结果:

js实现组合

function combinations(arr, k) {
  if (k === 0) return [[]];
  if (arr.length === 0) return [];

  const first = arr[0];
  const rest = arr.slice(1);

  const withFirst = combinations(rest, k - 1).map(comb => [first, ...comb]);
  const withoutFirst = combinations(rest, k);

  return [...withFirst, ...withoutFirst];
}

// 示例用法
console.log(combinations([1, 2, 3], 2)); 
// 输出: [[1, 2], [1, 3], [2, 3]]

迭代实现组合

使用位运算可以迭代生成所有可能的组合:

function combinationsIterative(arr, k) {
  const result = [];
  const n = arr.length;

  for (let mask = 0; mask < (1 << n); mask++) {
    if (countSetBits(mask) !== k) continue;

    const current = [];
    for (let i = 0; i < n; i++) {
      if (mask & (1 << i)) current.push(arr[i]);
    }
    result.push(current);
  }

  return result;
}

function countSetBits(num) {
  let count = 0;
  while (num) {
    count += num & 1;
    num >>= 1;
  }
  return count;
}

// 示例用法
console.log(combinationsIterative([1, 2, 3], 2));
// 输出: [[1, 2], [1, 3], [2, 3]]

使用生成器实现组合

ES6 生成器可以惰性地生成组合,节省内存:

js实现组合

function* combinationsGenerator(arr, k, start = 0, current = []) {
  if (current.length === k) {
    yield [...current];
    return;
  }

  for (let i = start; i < arr.length; i++) {
    current.push(arr[i]);
    yield* combinationsGenerator(arr, k, i + 1, current);
    current.pop();
  }
}

// 示例用法
const gen = combinationsGenerator([1, 2, 3], 2);
console.log([...gen]); 
// 输出: [[1, 2], [1, 3], [2, 3]]

处理大型数据集的优化

对于大型数据集,可以采用剪枝策略优化递归:

function optimizedCombinations(arr, k) {
  const result = [];

  function backtrack(start, path) {
    if (path.length === k) {
      result.push([...path]);
      return;
    }

    const maxRemaining = arr.length - (k - path.length) + 1;
    for (let i = start; i < maxRemaining; i++) {
      path.push(arr[i]);
      backtrack(i + 1, path);
      path.pop();
    }
  }

  backtrack(0, []);
  return result;
}

实际应用示例

从颜色列表中生成所有可能的双色组合:

const colors = ['red', 'green', 'blue', 'yellow'];
const colorPairs = combinations(colors, 2);

console.log(colorPairs);
// 输出: [['red', 'green'], ['red', 'blue'], ..., ['blue', 'yellow']]

这些方法覆盖了从基础到进阶的组合生成需求,可以根据具体场景选择最适合的实现方式。递归方法直观但可能堆栈溢出,迭代方法适合确定性问题,生成器适合流式处理大数据集。

标签: 组合js
分享给朋友:

相关文章

js实现抽奖

js实现抽奖

实现抽奖功能的基本思路 抽奖功能的核心是随机选择奖项并展示结果。可以通过数组存储奖项,利用随机数生成索引,最后通过动画增强用户体验。 准备奖项数据 定义一个数组存储奖项信息,每个奖项可以包含名称、图…

js实现授权

js实现授权

授权流程设计 授权流程通常涉及前端与后端的交互,常见方案包括OAuth2.0、JWT等。以JWT为例的典型流程: 用户提交凭证(如用户名密码)到认证服务 服务端验证通过后生成包含用户信息的J…

js实现代码雨

js实现代码雨

实现代码雨效果 使用HTML5 Canvas和JavaScript可以轻松实现经典的代码雨效果。以下是完整的实现代码和说明: HTML结构 <!DOCTYPE html> <htm…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…

js验证码的实现

js验证码的实现

验证码的基本实现原理 验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。 纯前端验证码…

js 实现日历

js 实现日历

实现日历的基本思路 日历的核心功能是展示日期,并允许用户进行日期选择或导航。JavaScript 可以动态生成日历的 HTML 结构,并处理用户交互逻辑。 基础日历结构 日历通常包含头部(显示月份和…