JavaScript如何实现元素全排列实例代码


Posted in Javascript onMay 14, 2019

排列 (Permutation / Arrangement)

概念

n 个不同元素中任意选取 m (m <= n) 个元素进行排列,所有排列情况的个数叫做 排列数,其值等于:

A = n! / (n - m)!

! 表示数学中的阶乘运算符,可以通过以下函数实现:

function factorial(n) {
 if (n === 0 || n === 1) {
 return 1;
 
 } else if (n < 0) {
 return null;
 
 } else {
 return n * factorial(n - 1);
 }
}

console.log(factorial(4)); // 24

当 n = m 时,称为 全排列,其值等于:

A = n!

全排列相当于将所有元素进行排序,得到所有不同顺序情况的个数;

分析

利用阶乘函数,通过上述数学公式只能得到所有情况的个数值,不容易得到具体的每种情况,要获取每种情况的输出值的话需要另寻他法;

用数组举例分析:

全排列:

    [1, 2, 3] => [             
                    [1, 2, 3],
                    [1, 3, 2],
                    [2, 1, 3],
                    [2, 3, 1],
                    [3, 1, 2],
                    [3, 2, 1]
                 ]
               
                共 6 种情况

    树状图表示:
   
      1       2       3
     / \     / \     / \
    2   3   1   3   1   2
    |   |   |   |   |   |
    3   2   3   1   2   1   =>  6

3 个元素中选取 2 个时:(n = 3, m = 2)

    [1, 2, 3] => [             
                    [1, 2],
                    [1, 3],
                    [2, 1],
                    [2, 3],
                    [3, 1],
                    [3, 2]
                 ]
               
                共 6 种情况
   
    树状图表示:
   
      1       2       3
     / \     / \     / \
    2   3   1   3   1   2   =>  6

实现

let arr = [1, 2, 3];

/*
参数 a 为输入数组,
元素个数 n 为 a 的长度,
选取个数为 m;
*/
function permutation(a, m) {

 // 保存最终输出结果
 let result = [];
 
 // 定义 m 值默认等于 n,即全排列
 let n = a.length;
 m = m || n;
 
 // 定义递归函数保存结果到数组中
 // _a 为输入数组,
 // tmpResult 为保存单个情况结果的数组
 function recur(_a, tmpResult = []) {
 if (tmpResult.length === m) {
 
  // 结果达到 m 个时保存结果,
  // 停止递归并进入下一次遍历
  result.push(tmpResult);
  
 } else {
  for (let i = 0; i < _a.length; i++) {
  
  // 复制一份输入数组,防止引用值被改变
  let tmpA = _a.concat();
  
  // 复制一份保存结果的数组,防止每次遍历相互影响
  let _tmpResult = tmpResult.concat();
  
  // 保存当前遍历值
  _tmpResult.push(tmpA[i]);
  
  // 删除当前遍历值,传递参数进入下一层递归
  tmpA.splice(i, 1);
  recur(tmpA, _tmpResult);
  }
 }
 }
 
 // 开始执行递归,然后返回最后结果
 recur(a);
 return result;
}

console.log(permutation(arr));
// 3 个数全排列:
/*
[  
 [1, 2, 3], 
 [1, 3, 2], 
 [2, 1, 3], 
 [2, 3, 1], 
 [3, 1, 2], 
 [3, 2, 1]
]
*/

console.log(permutation(arr, 2));
// 3 个数中选取 2 个数排列:
/*
[  
 [1, 2], 
 [1, 3], 
 [2, 1], 
 [2, 3], 
 [3, 1], 
 [3, 2]
]
*/

最终实现函数就是 permutation(a, m),其中参数 a 为输入数组,包含需要排列的所有元素,参数 m 为选取需要排列的个数,默认等于输入数组的长度,即默认全排列,注意 m 不能大于元素个数;

拓展

以上函数输出值为一个二维数组,如果需要便于观察,输出一个一维数组,可以定义一个合并函数:

function merge(arr) {
 return arr.map(x => x.join(''));
}

let result = merge(permutation([1, 2, 3]));
console.log(result);
// [123, 132, 213, 231, 312, 321]

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
简介AngularJS的HTML DOM支持情况
Jun 17 Javascript
jQuery网页右侧广告跟随滚动代码分享
Apr 20 Javascript
javascript结合Flexbox简单实现滑动拼图游戏
Feb 18 Javascript
JS实现DIV高度自适应窗口示例
Feb 16 Javascript
jquery.masonry瀑布流效果
May 25 jQuery
JS FormData上传文件的设置方法
Jul 05 Javascript
Vue 2.0学习笔记之Vue中的computed属性
Oct 16 Javascript
js数组常用最重要的方法
Feb 04 Javascript
微信小程序js文件改变参数并在视图上及时更新【推荐】
Jun 11 Javascript
vue 实现滚动到底部翻页效果(pc端)
Jul 31 Javascript
iSlider手机端图片滑动切换插件使用详解
Dec 24 Javascript
vue打开其他项目页面并传入数据详解
Nov 25 Vue.js
微信小程序实现多选框全选与取消全选功能示例
May 14 #Javascript
js中arguments对象的深入理解
May 14 #Javascript
ios中视频的最后一桢问题解决
May 14 #Javascript
详解可以用在VS Code中的正则表达式小技巧
May 14 #Javascript
vue项目中引入vue-datepicker插件的详解
May 14 #Javascript
JQuery获取可视区尺寸和文档尺寸及制作悬浮菜单示例
May 14 #jQuery
JavaScript中this的全面解析及常见实例
May 14 #Javascript
You might like
php 转换字符串编码 iconv与mb_convert_encoding的区别说明
2011/11/10 PHP
Drupal读取Excel并导入数据库实例
2014/03/02 PHP
PHP中explode函数和split函数的区别小结
2016/08/24 PHP
用正则表达式 动态创建/增加css style script 兼容IE firefox
2009/03/10 Javascript
JS实现随机乱撞彩色圆球特效的方法
2015/05/05 Javascript
JavaScript实现仿淘宝商品购买数量的增减效果
2016/01/22 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
2016/08/01 Javascript
AngularJS实现动态编译添加到dom中的方法
2016/11/04 Javascript
原生JavaScript实现AJAX、JSONP
2017/02/07 Javascript
使用Bootstrap + Vue.js实现添加删除数据示例
2017/02/27 Javascript
jQuery插件echarts实现的多柱子柱状图效果示例【附demo源码下载】
2017/03/04 Javascript
详解vue父子模版嵌套案例
2017/03/04 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
详解nodejs通过代理(proxy)发送http请求(request)
2017/09/22 NodeJs
Angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法
2017/10/24 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
2019/05/09 Javascript
解决vue-router 二级导航默认选中某一选项的问题
2019/11/01 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
JQuery Ajax如何实现注册检测用户名
2020/09/25 jQuery
[49:20]2014 DOTA2国际邀请赛中国区预选赛5.21 CIS VS TongFu
2014/05/22 DOTA
浅谈python中的正则表达式(re模块)
2017/10/17 Python
Python Socket使用实例
2017/12/18 Python
Python Json模块中dumps、loads、dump、load函数介绍
2018/05/15 Python
浅析Python 序列化与反序列化
2020/08/05 Python
波比布朗英国官网:Bobbi Brown英国
2017/11/13 全球购物
GAP阿联酋官网:GAP UAE
2017/11/30 全球购物
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
医药工作岗位求职信分享
2013/12/31 职场文书
毕业典礼主持词大全
2014/03/26 职场文书
《放小鸟》教学反思
2014/04/20 职场文书
高二学年自我鉴定范文(2篇)
2014/09/26 职场文书
幼儿园教研工作总结2015
2015/05/12 职场文书
低端且暴利的线上线下创业项目分享
2019/09/03 职场文书
解决SpringCloud Feign传对象参数调用失败的问题
2021/06/23 Java/Android
mysql如何查询连续记录
2022/05/11 MySQL