javascript如何返回字符串的所有排列

 更新时间:2023年01月17日 14:26:25   作者:黄元帅  
这篇文章主要介绍了javascript如何返回字符串的所有排列问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

js返回字符串的所有排列

需求

返回一个字符串所有的排列

  • 输入:一个字符串
  • 输出:一个包含该字符串所有排列情况的数组

代码

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)), []);
    }
};

效果

这里写图片描述

一点思路

递归、长度为阶乘

js实现字符串全排序

这是一道经典的算法题,学过排列组合的童鞋们都知道长度为n的字符串其全排序大小为n! (这里不考虑字符串里有重复字符,不做去重处理)。

网上有各种语言的实现算法,但js语言实现的比较少(果然藐视【划掉】忽略我广大前端er的算法水平)。另外,网上实现的多为递归方法。这里用非递归的js实现一下,轻拍。

先说一下思路:单个字符的串,比如a全排序为1(废话忽略)。

两个字符的串比如ab,全排序数为2,即:ab和ba。那我们不禁要问,你是怎么得到的?

解答如下:

  • 第一步————先拿出a,那么a的前面和a的后面产生两个空位,如图:0 a 0。
  • 第二步————将b分别放在两个空位里,得到ba和ab。
  • 第三步————sorry,没有第三步。

好了,那三个字符abc你怎么办?

其实还是老办法,只不过我们是建立在刚才的2个字符组成的串已经全排完的基础上。

  • 第一步————拿出刚才产生的ba,它产生了三个空位,如图:0 b 0 a 0.
  • 第二步————把剩余的c分别插入这三个空位,得到cba,bca和bac。
  • 现在我们的ba已经被利用完了,还有ab没用,ok,我们现在来用它重复上面的步骤,得到cab,acb和abc。

那四个字符abcd组成的串呢?

聪明的你一定想到用刚才三个字符产生的结果,每个串生成4个空位,然后把d分别放在这4个空位里。

至此,我们的算法思路就已经说完了。现在开始用代码实现。

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JavaScript编程的10+最佳实践解决方案

    JavaScript编程的10+最佳实践解决方案

    在现代Web开发中,JavaScript已经成为无法替代的核心技术,在现代Web开发中,JavaScript已经成为无法替代的核心技术,本文将通过代码示例详细介绍一些实践解决方案,感兴趣的同学可以参考下
    2023-06-06
  • JS中的Date()使用小结

    JS中的Date()使用小结

    Date() 日期对象是一个构造函数必须使用new来调用创建我们的日期对象,本文给大家介绍JS中的Date()使用小结,感兴趣的朋友一起看看吧
    2024-01-01
  • 解读new Object()和Object.create()的区别

    解读new Object()和Object.create()的区别

    这篇文章主要介绍了解读new Object()和Object.create()的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 浅谈JS继承_借用构造函数 & 组合式继承

    浅谈JS继承_借用构造函数 & 组合式继承

    下面小编就为大家带来一篇浅谈JS继承_借用构造函数 & 组合式继承。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • 原生JavaScript实现连连看游戏(附源码)

    原生JavaScript实现连连看游戏(附源码)

    原生JavaScript版连连看游戏,有源码,适合初学者学习,喜欢的朋友可以研究下
    2013-11-11
  • JS中数组常用的循环遍历你会几种

    JS中数组常用的循环遍历你会几种

    JS 遍历数组(循环数组)的方式有多种,但你都知道吗?下面这篇文章主要给大家介绍了关于JS中数组常用循环遍历的相关资料,需要的朋友可以参考下
    2021-06-06
  • js实现拖动缓动效果

    js实现拖动缓动效果

    这篇文章主要为大家详细介绍了js实现拖动缓动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-01-01
  • 有关JavaScript的10个怪癖和秘密分享

    有关JavaScript的10个怪癖和秘密分享

    在本片文章中,作者将向您讲述JavaScript中最鲜为人知的秘密。学习js的朋友可以参考下。
    2011-08-08
  • layer弹出层自适应高度,垂直水平居中的实现

    layer弹出层自适应高度,垂直水平居中的实现

    今天小编就为大家分享一篇layer弹出层自适应高度,垂直水平居中的实现,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 鼠标经过tr时,改变tr当前背景颜色

    鼠标经过tr时,改变tr当前背景颜色

    本篇文章主要介绍了鼠标经过tr时,改变tr当前背景颜色的示例代码,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01

最新评论