Это мое решение из следующего ответа: https://stackoverflow.com/a/18879232/783743
var permute = (function() {
return permute;
function permute(list) {
return list.length ?
list.reduce(permutate, []) :
[[]];
}
function permutate(permutations, item, index, list) {
return permutations.concat(permute(
list.slice(0, index).concat(
list.slice(index + 1)))
.map(concat, [item]));
}
function concat(list) {
return this.concat(list);
}
}());
Вы можете использовать функцию permute
для нахождения всех перестановок массива:
var array = "ahimrsu".split("");
var permutations = permute(array).map(join);
var index = permutations.indexOf("maruish");
function join(array) {
return array.join("");
}
Алгоритм очень прост для понимания:
- Мы хотим, чтобы функция
permute
типа [a] -> [[a]]
(т.е. заданный список a
s, он возвращает список перестановок ввода).
- Учитывая пустой список (
[]
), вход представляет собой пустой список перестановок ([[]]
).
- В противном случае для каждого элемента:
- Мы удаляем элемент из списка.
- Мы рекурсивно находим перестановки остальных элементов.
- Мы добавим элемент, который мы удалили в начало каждой перестановки.
Например, предположим, что мы хотим найти перестановку массива [1, 2, 3]
:
1. permute([1, 2, 3]) === [1, 2, 3].reduce(permutate, [])
1. permutate([], 1, 0, [1, 2, 3])
1. permute([2, 3]) === [2, 3].reduce(permutate, [])
1. permutate([], 2, 0, [2, 3])
1. permute([3]) === [3].reduce(permutate, [])
1. permutate([], 3, 0, [3])
1. permute([]) === [[]]
2. [[]].map(concat, [3]) === [[3]]
3. [].concat([[3]]) === [[3]]
2. [[3]].map(concat, [2]) === [[2, 3]]
3. [].concat([[2, 3]]) === [[2, 3]]
2. permutate([[2, 3]], 3, 1, [2, 3])
1. permute([2]) === [2].reduce(permutate, [])
1. permutate([], 2, 0, [2])
1. permute([]) === [[]]
2. [[]].map(concat, [2]) === [[2]]
3. [].concat([[2]]) === [[2]]
2. [[2]].map(concat, [3]) === [[3, 2]]
3. [[2, 3]].concat([[3, 2]]) === [[2, 3], [3, 2]]
2. [[2, 3], [3, 2]].map(concat, [1]) === [[1, 2, 3], [1, 3, 2]]
3. [].concat([[1, 2, 3], [1, 3, 2]]) === [[1, 2, 3], [1, 3, 2]]
2. permutate([[1, 2, 3], [1, 3, 2]], 2, 1, [1, 2, 3])
1. permute([1, 3]) === [1, 3].reduce(permutate, [])
2. [[1, 3], [3, 1]].map(concat, [2]) === [[2, 1, 3], [2, 3, 1]]
3. [[1, 2, 3], [1, 3, 2]].concat([[2, 1, 3], [2, 3, 1]])
3. permutate([[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]], 3, 2, [1, 2, 3])
1. permute([1, 2]) === [1, 2].reduce(permutate, [])
2. [[1, 2], [2, 1]].map(concat, [3]) === [[3, 1, 2], [3, 2, 1]]
3. [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1]].concat([[3, 1, 2], [3, 2, 1]])
Старый объяснение:
- Сначала удалить первый элемент списка. Следовательно, у нас есть пункт
1
и список [2, 3]
.
- Далее мы найдем перестановки
[2, 3]
.
- Мы удаляем первый элемент. Следовательно, у нас есть пункт
2
и список [3]
.
- Далее мы найдем перестановки
[3]
.
- Мы удаляем первый элемент. Следовательно, у нас есть пункт
3
и список []
.
- Далее мы найдем перестановки
[]
, которые являются [[]]
.
- Мы добавляем
3
в начало каждой перестановки.
- Результат
[[3]]
.
- Мы добавляем
2
в начало каждой перестановки.
- Результат
[[2, 3]]
.
- Мы удаляем второй элемент. Следовательно, у нас есть пункт
3
и список [[2]]
.
- Далее мы найдем перестановки
[2]
.
- Мы удаляем первый элемент. Следовательно, у нас есть пункт
2
и список []
.
- Далее мы найдем перестановки
[]
, которые являются [[]]
.
- Мы добавляем
2
в начало каждой перестановки.
- Результат
[[2]]
.
- Мы добавляем
3
в начало каждой перестановки.
- Результат
[[3, 2]]
.
- Мы объединяем два списка.
- Результат
[[2, 3], [3, 2]]
.
- Мы добавляем
1
в начало каждой перестановки.
- Результат
[[1, 2, 3], [1, 3, 2]]
.
- То же самое касается второго элемента: item
2
и список [1, 3]
.
- То же самое для третьего элемента: item
3
и список [1, 2]
.
- Мы объединяем три списка.
- Результат
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
.
Смотреть демо:
var permute = (function() {
return permute;
function permute(list) {
return list.length ?
list.reduce(permutate, []) :
[[]];
}
function permutate(permutations, item, index, list) {
return permutations.concat(permute(
list.slice(0, index).concat(
list.slice(index + 1)))
.map(concat, [item]));
}
function concat(list) {
return this.concat(list);
}
}());
var array = "ahimrsu".split("");
var permutations = permute(array).map(join);
var index = permutations.indexOf("maruish");
alert("maruish is the " + (index + 1) + "th permutation of ahimrsu.");
function join(array) {
return array.join("");
}
Надежда, что помогает.
Алгоритма строки перестановки будет рекурсивным (простейшие). – dfsq
Он покажет все комбинации этих букв. –
Дайте мне несколько минут, чтобы закодировать его. – dfsq