You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成无节拍偏移重复的3-11拍1-12音符旋律字符串?

旋律组合生成需求与算法实现

需求概述

需要生成满足以下条件的所有旋律字符串:

  • 旋律时长范围:3至11拍
  • 可用音符数量范围:1至12个
  • 排除仅因节拍偏移导致重复的旋律(例如1 2 3 4 1 2 3 4和2 3 4 1 2 3 4 1视为重复,只保留其中一种)

旋律示例

[4/4拍]
1 2 3 4 1 2 3 4 ...
[5/4拍]
1 2 1 2 3 1 2 1 2 3 ...
1 2 3 4 5 1 2 3 4 5 ...
2 3 4 5 6 2 3 4 5 6 ...

需要排除的重复类型

1 2 3 4 1 2 3 4 ...
2 3 4 1 2 3 4 1 ...
3 4 1 2 3 4 1 2 ...

目标算法逻辑

期望实现的核心逻辑如下:

function getMelodies(numBeats, numNotes) {
  // 1. 生成所有符合音符数量要求的音符组合
  // 2. 生成每个组合的所有变体
  // 3. 过滤掉因节拍偏移产生的重复项
}

现有代码问题

当前尝试的代码仅固定生成4拍相关的有限组合,既未覆盖3-11拍的时长范围,也未处理音符数量的动态变化,更没有实现去重逻辑,无法满足需求:

function getMelodies(beats, notes) {
  let array = []
  let i = 0
  while (i < notes) {
    array.push([i, i, i, i])
    array.push([i, i + 1, i + 1, i + 1]);
    array.push([i, i + 2, i + 2, i + 2]);
  }
}

参考结论

根据数学推导,当节拍数为4、可用音符数为7时,符合要求的旋律共有616种。

改进实现思路与代码

核心步骤拆解

  1. 生成基础音符序列:根据指定节拍数和可用音符数,生成所有对应长度的音符序列(每个位置取1到可用音符数的整数)
  2. 去重节拍偏移重复项:对每个序列生成所有循环偏移变体,仅保留每个等价类的唯一代表(如取字典序最小的序列)
  3. 覆盖多范围参数:遍历3至11的所有节拍数、1至12的所有可用音符数,收集所有符合条件的旋律

实现代码

function getMelodies(minBeats = 3, maxBeats = 11, minNotes = 1, maxNotes = 12) {
  const allMelodies = new Set();

  // 遍历所有符合要求的节拍数与可用音符数组合
  for (let numBeats = minBeats; numBeats <= maxBeats; numBeats++) {
    for (let numNotes = minNotes; numNotes <= maxNotes; numNotes++) {
      // 递归生成所有长度为numBeats的音符序列
      const generateSequences = (length, current = []) => {
        if (current.length === length) {
          // 生成当前序列的所有循环偏移变体
          const variants = [];
          for (let offset = 0; offset < length; offset++) {
            const variant = [...current.slice(offset), ...current.slice(0, offset)];
            variants.push(variant.join(' '));
          }
          // 取字典序最小的变体作为唯一标识,避免节拍偏移重复
          const uniqueKey = variants.sort()[0];
          allMelodies.add(uniqueKey);
          return;
        }
        // 填充每个位置的可能音符
        for (let note = 1; note <= numNotes; note++) {
          generateSequences(length, [...current, note]);
        }
      };
      generateSequences(numBeats);
    }
  }

  return Array.from(allMelodies);
}

// 示例:验证4拍7音的旋律数量(应返回616)
const fourBeatSevenNotes = getMelodies(4, 4, 7, 7);
console.log(fourBeatSevenNotes.length); // 输出616

内容的提问来源于stack exchange,提问作者Lance Pollard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 14:17:50