下面是两个版本,第一个是AS3,第二个是AS2。这是一个稍微不同的算法(它与你所拥有的算法相比效率稍低,但我认为它会作为一个例子)。它基本上是相同的算法复杂性,所以没关系,冗余是生成中间结果(较短的数组),后来被丢弃(但如果这涉及到你可以修改它以重用这些数组)。
AS3
private function permuteRecursively(input:Array,
hash:Object = null):Array
{
var first:String;
var oldResult:Array;
var newResult:Array;
var times:int;
var current:Array;
var test:String;
if (input.length > 1)
{
first = input.shift();
if (!hash) hash = { };
oldResult = this.permuteRecursively(input, hash);
newResult = [];
for each (var result:Array in oldResult)
{
times = result.length;
while (times >= 0)
{
current = result.concat();
if (times == result.length) current.push(first);
else current.splice(times, 0, first);
test = current.join("");
if (!(test in hash))
{
newResult.push(current);
hash[test] = 1;
}
times--;
}
}
}
else newResult = [input];
return newResult;
}
AS2:
private function permuteRecursively(input:Array,
hash:Object):Array
{
var first:String;
var oldResult:Array;
var newResult:Array;
var times:Number;
var current:Array;
var test:String;
var result:Array;
if (input.length > 1)
{
first = input.shift();
if (!hash) hash = { };
oldResult = this.permuteRecursively(input, hash);
newResult = [];
for (var i:Number = 0; i < oldResult.length; i++)
{
result = oldResult[i];
times = result.length;
while (times >= 0)
{
current = result.concat();
if (times == result.length) current.push(first);
else current.splice(times, 0, first);
test = current.join("");
if (!(test in hash))
{
newResult.push(current);
hash[test] = 1;
}
times--;
}
}
}
else newResult = [input];
return newResult;
}
编辑:
其实,现在我想起来了,我不知道你正在尝试什么样的复制品避免。上面的代码将AAC和ACA的排列看作是不同的(即使A是“重复”的),但AAC和AAC被认为是相同的(即使第一个A和第二个A可能会出现来自原始数组中的不同来源)。
如果你想删除生成数组的重复元素,那么很明显,最好的策略是先从源代码中删除它们。