假设我们有元素0和1,它们可以多次出现,例如00 00 11,00 00 11 11或01 11(分成2组以提高可读性)。我已经有一个生成所有唯一排列的函数:class UniqueElement { constructor(value, occurrences) { this.value = value; this.occurrences = occurrences; }}function permUnique(elements) { let set = new Set(elements); let listunique = Array.from(set).map((i) => new UniqueElement(i, elements.filter((el) => el === i).length)); let u = elements.length; return permUniqueHelper(listunique, "0".repeat(u).split("").map((i) => parseInt(i)), u - 1);}function* permUniqueHelper(listunique, result_list, d) { if (d < 0) { yield [...result_list]; } else { for (const i of listunique) { if (i.occurrences > 0) { result_list[d] = i.value; i.occurrences--; for (const g of permUniqueHelper(listunique, result_list, d - 1)) yield g; i.occurrences++; } } }}// call like:// permUnique([0,0,1,1])console.log(Array.from(permUnique([0,0,1,1])).join('\n'));从这里翻译成JavaScript:https://stackoverflow.com/a/6285203/10362619现在,我的意图是使用这些生成的排列作为其他对象的索引。然后在代码中使用这些对象,这些对象的顺序无关紧要:10 1001 01到底是一样的,还是01 20 1202 10 2110 21 0212 01 20...从0开始具有1,2和00 11 22的基数。它们被认为是相同的,因为相同的数字位于相同的位置。只需切换两个数字(例如0与1),您就会得到另一个。同样,所有这些示例都被分为两组,以提高可读性。 00 11 22的含义与001122相同,其中每个数字都是输入数组中的单个元素。创建排列后,是随后过滤元素的最快方法,还是可以在函数中实现此条件?编辑:不需要它是置换数组的生成器函数编辑2:为了使事情更清楚:我给出的第一个示例具有模式abab,其中a可以是0或1,而b相反。第二个示例遵循模式abcabc,其中a,b和c都可以是0,1或2(但不相同)。 最佳答案 在不同排列之间具有相等条件之后,我们需要为每个模式(相等类)建立规范形式。然后,我们将尝试仅生成那些。在您的情况下,1,2 s和3的顺序无关紧要,我们可以确定它们各自的首次出现必须以123的顺序出现,并且2在没有和1并非没有3。因此,无论模式是2,aabcbc,aacbcb,…还是bbacac,我们要生成的唯一形式是ccbaba。或者,当模式为112323 / aaa / bbb时,我们仅生成ccc,而不会生成111或222。然后,我们可以编写一种遵循以下规则的规范形式的算法:function patterns(values, len) { function* recurse(list, used, depth) { if (depth == len) { yield list.slice(); } else { for (let j=0; j<used; j++) { // only put already used values at this position list[depth] = values[j]; yield* recurse(list, used, depth+1); } if (used < values.length) { // or the single next unused value list[depth] = values[used]; yield* recurse(list, used+1, depth+1); // which is counted as used here } } } return recurse([], 0, 0);}这只是从不同的333生成一定长度的所有组合,但是您可以在算法中使用从一定数量的非唯一值生成置换的相同方法。但是,它确实变得更加复杂:如果只有值values可用,则无法实现规范形式121,但仍应生成模式122。我们需要调整规则,以使排序要求仅在出现次数相同的元素之间。因此,我们必须为它们保留不同的212计数。function permutationPatterns(elements) { const len = elements.length; const unique = new Map(elements.map(el => [el, {value: el, occurrences: 0}])); let max = 0; for (const el of elements) { const o = unique.get(el); max = Math.max(max, ++o.occurrences); } const byOccurrences = Array.from({length: max+1}, () => ({elements: [], used: 0})); for (const o of unique.values()) { byOccurrences[o.occurrences].elements.push(o); } function* generate(list, depth) { if (depth == len) { yield list.slice(); } else { for (const options of byOccurrences) { options.used++; for (const option of options.elements.slice(0, options.used)) { if (option.occurrences == 0) continue; option.occurrences--; list[depth] = option.value; yield* generate(list, depth+1); option.occurrences++; } options.used--; } } } return generate([], 0);}关于javascript - JavaScript中具有重复元素的唯一排列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56672545/
10-11 23:11