标签:javascript algorithm permutation
有一个带有一些符号的小数组,如[‘^’,’^’,’>’,’>’,”,’<','<'],我怎样才能获得所有不同的排列?我知道类似的问题已被提出(并且已经有一些很好的答案),如:
> Shuffle an array as many as possible
> Permutations in JavaScript?
但是它们没有呈现出独特的结果.我怎样才能有效地获得每个可能的结果一次?
解决方法:
对于小数组,您可以使用其中一个引用的算法,将每个排列映射到一个字符串,并将整个数组抛出到Set中以丢弃重复项.就像是:
let a = ['^','^','>','>','+','<','<'];
let ps = permutations(a); // return value should be array of arrays.
let qs = ps.map(p => p.join(""));
let s = new Set(qs);
对于具有<的数组,这应该可以正常工作10个符号. 否则,请参阅here和here,了解可以转换为JavaScript的各种方法.
一种流行的方法是Pandita algorithm,其使用连续规则列举词典顺序中的排列,有效地仅生成“唯一”排列. here和here给出了这种方法的简短说明.这是一个JavaScript(ES6)实现:
function swap(a, i, j) {
const t = a[i];
a[i] = a[j];
a[j] = t;
}
function reverseSuffix(a, start) {
if (start === 0) {
a.reverse();
}
else {
let left = start;
let right = a.length - 1;
while (left < right)
swap(a, left++, right--);
}
}
function nextPermutation(a) {
// 1. find the largest index `i` such that a[i] < a[i + 1].
// 2. find the largest `j` (> i) such that a[i] < a[j].
// 3. swap a[i] with a[j].
// 4. reverse the suffix of `a` starting at index (i + 1).
//
// For a more intuitive description of this algorithm, see:
// https://www.nayuki.io/page/next-lexicographical-permutation-algorithm
const reversedIndices = [...Array(a.length).keys()].reverse();
// Step #1; (note: `.slice(1)` maybe not necessary in JS?)
const i = reversedIndices.slice(1).find(i => a[i] < a[i + 1]);
if (i === undefined) {
a.reverse();
return false;
}
// Steps #2-4
const j = reversedIndices.find(j => a[i] < a[j]);
swap(a, i, j);
reverseSuffix(a, i + 1);
return true;
}
function* uniquePermutations(a) {
const b = a.slice().sort();
do {
yield b.slice();
} while (nextPermutation(b));
}
let a = ['^','^','>','>','+','<','<'];
let ps = Array.from(uniquePermutations(a));
let qs = ps.map(p => p.join(""));
console.log(ps.length);
console.log(new Set(qs).size);
nextPermutation函数将数组就地转换为词典后继,或者如果数组已经是字典最大值,则将字典转换为词典最小值.在第一种情况下,它返回true,否则返回false.这允许您循环遍历从最小(已排序)数组开始直到nextPermutation翻转并返回false的所有排列.
标签:javascript,algorithm,permutation 来源: https://codeday.me/bug/20191002/1841271.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。