下面是兩個版本,第一個是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可能會出現來自原始數組中的不同來源)。
如果你想刪除生成數組的重複元素,那麼很明顯,最好的策略是先從源代碼中刪除它們。