JavaScript实现字符串全排列的两种方法:递归与非递归
本文介绍如何在JavaScript中生成字符串的所有排列。首先通过递归方法利用reduce和map处理字符插入,其次展示基于数组操作的迭代思路,即利用前一步生成的排列结果,在当前字符串的每个空位插入新字符。文章包含完整代码示例及运行输出,适用于理解排列组合算法在前端开发中的应用。
JavaScript实现字符串的所有排列
需求说明
目标是生成并返回给定字符串的所有可能排列组合。
- 输入参数为一个字符串。
- 输出结果为一个包含该字符串所有排列情况的数组。
代码实现
const anagrams = str => {
if (str.length <= 2) {
return str.length === 2 ? [str, str[1] + str[0]] : [str];
}
else{
return str.split('').reduce((acc, letter, i) =>
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []);
}
};运行效果展示

核心思路解析
主要采用递归思想,排列总数为字符串长度的阶乘。
JavaScript实现字符串全排序
这是一道经典的算法题目。根据排列组合原理,长度为n且不含重复字符的字符串,其全排列的数量为n!(此处暂不考虑去重处理)。
网络上存在多种编程语言的实现方案,但专门针对JavaScript的实现相对较少(这或许反映了前端开发者在算法领域的关注度)。此外,常见的实现多依赖于递归方法。本文尝试提供一种非递归的JavaScript实现方式。
首先阐述基本思路:对于单个字符的字符串,其全排列数量仅为1。
对于两个字符的字符串(例如ab),全排列数量为2,即ab和ba。那么,我们是如何得到这些结果的?
具体推导过程如下:
- 第一步:取出字符a,此时a的前后形成两个空位,示意如下:0 a 0。
- 第二步:将字符b分别插入到这两个空位中,从而得到ba和ab。
- 第三步:对于双字符情况,过程至此结束。
那么,面对三个字符abc的情况,该如何处理?
基本逻辑不变,但基于前一步两个字符已全排列的结果进行扩展。
- 第一步:取之前生成的排列ba,它产生了三个空位,示意如下:0 b 0 a 0。
- 第二步:将剩余字符c分别插入这三个空位,得到cba、bca和bac。
- 接着处理另一个前序排列ab,重复上述步骤,将c插入其产生的空位,得到cab、acb和abc。
如果是四个字符abcd组成的字符串呢?
逻辑一致:利用三个字符产生的所有排列结果,为每个排列生成4个空位,然后将字符d分别插入这些空位中。
至此,算法思路阐述完毕,接下来通过代码进行实现。
function myPermutation(str){
// 空字符串直接返回吧
if(str.length === 0){
console.log('The string you input have No length!');
return;
}
// 一个字符也不用运算
if(str.length === 1){
console.log('The result array is: ' + str, '-&- The array length is: ' + str.length);
return;
}
// 长度2以上的开始计算
/* 先把字符串转成数组,因为js里关于字符串的函数不多,而关于数组的函数很多,所以中间步骤我们都用数组处理,比较方便 */
var arrayStr = str.split('');
/* 定义一个中间数组,作为每次大循环的根基。比如,你开始拿第3个字符去填充空位,那前2个字符的全排列就已经都存储在中间数组里了 */
// 你开始拿第4个字符去填充空位,那前3个字符的全排列就已经都存储在中间数组里了
var transArray = [];
/* 先把字符串的第1个字符存入中间数组,这是我们盖高楼的地基。此字符产生的两个空位,我们拿第2个字符开始去填充 */
transArray.push(arrayStr[0]);
// 定义一个存储最终结果的数组,作为返回值
var resultArray = [];
/* 第一层循环,从第2个字符开始,每次向字符串后取一个字符,往 中间数组 的每个字符串的 空位 里插 */
for(var i = 1; i < arrayStr.length; i++){
resultArray = [];
// 每次新取到的字符
var addChar = arrayStr[i];
/* 第二层循环,取一个 中间数组里 用以形成空位的 字符串,中间数组的长度就是此新字符前面的所有字符形成的全排列个数 */
for(var j = 0; j < transArray.length; j++){
// 依次取中间数组里的串
var toBeInsertStr = transArray[j];
// 用空格分割字符串,从而产生空位
var toBeInsertStrArray = toBeInsertStr.split('');
// 第三层循环,将取到的新字符分别放到空位上形成字符串,有多少空位就循环几次
for (var k = 0; k <= transArray[j].length; k++){
tempArray = toBeInsertStrArray.concat();
// 用splice函数处理,表示将字符填入空位
var insertedArray = toBeInsertStrArray.splice(k, 0, addChar);
// 刚才是数组操作,现在转成字符串
var transArrayItem = toBeInsertStrArray.join('');
// 将字符串压入结果数组
resultArray.push(transArrayItem);
toBeInsertStrArray = tempArray.concat();
}
}
transArray = [];
transArray = resultArray.concat();
}
console.log('The result array is: ' + resultArray, '-&- The array length is: ' + resultArray.length);
}
myPermutation('');
myPermutation('a');
myPermutation('ab');
myPermutation('abc');程序运行结果如下:
The string you input have No length! The result array is: a -&- The array length is: 1 The result array is: ba,ab -&- The array length is: 2 The result array is: cba,bca,bac,cab,acb,abc -&- The array length is: 6
总结
以上为个人经验分享,希望能提供有益参考,也希望大家多多支持本站。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
