我有一个问题,我无法解决这个问题,我希望有人可以帮助我。
想象一下以下情况:
有一个人名单都有名字。所以每个人都是一个名字""属性。从该列表中,随机顺序选择随机数量的人(因此并非所有人总是在选择中),并且每个人被选择不超过一次。但是,名称可能不是唯一的:列表中可能有多个人名为" Smith"。对于这个例子,让我们想象每个名字只是字母表中的一个字母。所以我可能会收到以下选择:
[V,C,R,C,F,X,R,C]
下一次选择可能完全不同。该选择中的每个元素都是不同的人,但有些名称不止一次出现。
让我们添加数字以澄清:
[V, C1, R1, C2, F, X, R2, C3]
现在我需要所有可能的人员组合,其中每个名称只出现一次,但尊重他们在选择中列出的顺序。选择中的每个唯一名称都应该在组合中 例如,在这种情况下,我需要:
[V, C1, R1, F, X],
[V, R1, C2, F, X],
[V, R1, F, X, C3],
[V, C1, F, X, R2],
[V, C2, F, X, R2]
...
等等。人们的职位不应该改变(即[C1,V,...]不会好,因为" V"不应该在" C1")之后。
我假设我需要递归和某种方式来跟踪名称,但这就是我的大脑开始融化的地方。 ;-)我发现脚本可以按任何顺序获得所有可能的排列,但不是这样的。
有人可以帮帮我吗?
谢谢!
答案 0 :(得分:0)
您可以采用一个组合算法,该算法在结果集中取一个项目(在检查相同的第一个字母不在临时结果集中之后),然后继续下一个索引,直到找到所需的长度或不有更多项目可供选择。
function getCombinations(array, size) {
function fork(i, t) {
if (t.length === size) {
result.push(t);
return;
}
if (i === array.length) {
return;
}
if (!t.some(([c]) => c === array[i][0])) {
fork(i + 1, t.concat([array[i]]));
}
fork(i + 1, t);
}
var result = [];
fork(0, []);
return result;
}
var data = ['V', 'C1', 'R1', 'C2', 'F', 'X', 'R2', 'C3'],
result = getCombinations(data, 5);
console.log(result.map(a => a.join(' ')));
答案 1 :(得分:0)
这是一个简单的非递归算法。
list = ['V', 'C1', 'R1', 'C2', 'F', 'X', 'R2', 'C3']; //
// build an index item => its positions
// (in your case item[0] == item.name)
let index = new Map;
for (let [i, item] of list.entries())
index.set(item[0], (index.get(item[0]) || new Set).add(i));
// start with a single combination which is the initial list
let combs = [list];
// for each item and its positions...
for (let [item, is] of index) {
// generate a new set of combinations
let combs2 = [];
// for each position...
for (let i of is) {
// all positions of this item, except of the current one
let toRemove = new Set([...is]);
toRemove.delete(i);
// for all combinations...
for (let c of combs) {
// insert null at these positions
combs2.push(c.map((x, j) => toRemove.has(j) ? null : x));
}
}
// continue with the new set of combinations
combs = combs2;
}
// once we're ready remove all null values
combs = combs.map(c => c.filter(x => x !== null))
// done
for (let c of combs)
console.log(c.join())