Как получить массив всей перестановки в Actionscript 3.0? - PullRequest
1 голос
/ 20 апреля 2019

Предположим, у меня есть массив A = [0,1,2]. Как получить 2-мерный массив perm_A = [[0,1,2], [0,2,1] [1,0,2] [1,2,0] [2,1,0], [2] , 0,1]? Порядок, в котором перестановка appper в perm_A не имеет значения.

Я использовал код в Алгоритм кучи .

function generatePermute(k:int, arr:Array){
        if (k == 1){
        perm_list.push(arr);
    }
    else {
        generatePermute(k-1,arr);
    }
    for (var i = 0; i < k-1; i++){
        if (k % 2 == 0){
            swap_arr(arr, i, k-1);
        }
        else{
            swap_arr(arr, 0, k-1);
        }
        generatePermute(k-1,arr);
    }
}

function swap_arr(input, index_A, index_B) {
    var temp = input[index_A];
 
    input[index_A] = input[index_B];
    input[index_B] = temp;
}

var arr:Array = [0,1,2, 3]
var perm_list:Array = new Array();
generatePermute(4,arr);
for (var i = 0; i<perm_list.length;i++){
    trace(perm_list[i])
}

Результат:

1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0
1,2,3,0

что явно не так.

обновление

если я изменю perm_list.push (arr); проследить (обр), я получаю правильный результат. Тем не менее, это только выводит все перестановки в консоли. Я хочу собрать все эти перестановки в двумерный массив.

function generatePermute(k:int, arr:Array){
    if (k == 1){
        trace(arr)
    }
    else {
        generatePermute(k-1,arr);
    }
    for (var i = 0; i < k-1; i++){
        if (k % 2 == 0){
            swap_arr(arr, i, k-1);
        }
        else{
            swap_arr(arr, 0, k-1);
        }
        generatePermute(k-1,arr);
    }
}

function swap_arr(input, index_A, index_B) {
    var temp = input[index_A];
 
    input[index_A] = input[index_B];
    input[index_B] = temp;
}

var arr:Array = [0,1,2, 3]
var perm_list:Array = new Array();
generatePermute(4,arr);

который выводит

0,1,2,3
1,0,2,3
2,0,1,3
0,2,1,3
1,2,0,3
2,1,0,3
3,1,0,2
1,3,0,2
0,3,1,2
3,0,1,2
1,0,3,2
0,1,3,2
0,2,3,1
2,0,3,1
3,0,2,1
0,3,2,1
2,3,0,1
3,2,0,1
3,2,1,0
2,3,1,0
1,3,2,0
3,1,2,0
2,1,3,0
1,2,3,0

Похоже, что-то не так с perm_list.push (arr)

1 Ответ

4 голосов
/ 20 апреля 2019

Я думаю, что нашел твою настоящую ошибку.Вы заполняете результат Array ссылками на arr , поэтому в итоге результат будет выглядеть как [arr, arr, arr, arr, arr ... arr] .Вы не помещаете туда текущую копию, вы помещаете ссылку на фактический объект, над которым работаете, и впоследствии изменяете тот же объект.Ключ заключается в том, чтобы скопировать текущее состояние вашего arr в отдельный объект.

var A:Array = new Array;

permutations([1, 2, 3, 0], 0, A);

trace(A.join("\n"));

function permutations(values:Array, index:uint, result:Array):void
{
    var i:uint;
    var len:uint = values.length;

    if (index == len)
    {
        // Look at the ".slice()" here, it is why
        // this one is working as expected.
        result.push(values.slice());
        return;
    }

    for (i = index; i < len; i++)
    {
        swap(values, index, i);
        permutations(values, index + 1, result);
        swap(values, index, i);
    }
}

function swap(list:Array, from:uint, to:uint):void
{
    var temp:* = list[from];
    list[from] = list[to];
    list[to] = temp;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...