我的目标是创建一个通用函数,该函数基于给定的模板和参数,创建一个填充了置换(向量)的二维向量,如下所示:
{0, 1, 0, -1, 3, -1}
,则意味着排列仅根据-1
处的数字而变化。
n
。 n-1
是排列可以包含的整数范围。例如。如果n = 4
,则向量中只能出现0, 1, 2, 3
length
,即向量的长度请注意,如果模板中已经存在一个数字,则不会在排列中生成该数字。
因此,举个例子:
n = 6, length = 5, template = {2, 1, 0, -1, 0, -1}
the permutations are:
{2, 1, 0, 3, 0, 3}
{2, 1, 0, 3, 0, 4}
{2, 1, 0, 3, 0, 5}
{2, 1, 0, 4, 0, 3}
{2, 1, 0, 4, 0, 4}
{2, 1, 0, 4, 0, 5}
{2, 1, 0, 5, 0, 3}
{2, 1, 0, 5, 0, 4}
{2, 1, 0, 5, 0, 5}
如您所见,数字仅在索引3和5(位置为-1
的位置中生成),并且不包含0, 1 or 2
的位置,因为它们已经出现在模板。
我需要在不使用<algorithm>
库的情况下生成这些排列。
我认为创建递归函数是最好的选择,但是我不知道如何前进。任何建议都会有所帮助。
谢谢
答案 0 :(得分:1)
由于您没有提供任何可见的尝试,因此我认为这可能对您学习一些有效的代码很有帮助。这是用JavaScript编写的(我希望它能产生预期的输出)。我希望它能为您提供一些您可以转换为C ++的想法。
function f(template){
console.log(JSON.stringify(template));
var used = template.reduce((acc, x) => { if (x != -1) acc.add(x); return acc; }, new Set());
console.log(`used: ${Array.from(used)}`);
var needed = new Set(template.reduce((acc, x, i) => { if (!used.has(i)) acc.push(i); return acc; }, []));
console.log(`needed: ${Array.from(needed)}`);
var indexes = template.reduce((acc, x, i) => { if (x == -1) return acc.concat(i); else return acc; }, []);
console.log(`indexes: ${indexes}`);
function g(needed, indexes, template, i=0){
if (i == indexes.length)
return [template];
var result = [];
// Each member of 'needed' must appear in
// each position, indexes[i]
for (x of needed){
let _template = template.slice();
_template[ indexes[i] ] = x;
result = result.concat(
g(needed, indexes, _template, i + 1));
}
return result;
}
return g(needed, indexes, template);
}
var template = [2, 1, 0, -1, 0, -1];
var result = f(template);
var str = '\n';
for (let r of result)
str += JSON.stringify(r) + '\n';
console.log(str);