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

排列 (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]

总结

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

(0)

相关推荐

  • 特漂亮的JS图片排列旋转效果代码

    了下代码,感觉用数组模拟有些僵硬,自己重新写了一个,请大家来pp! body{background:black} .point{position:absolute;height:75px;border:1px silver solid} #round{position:absolute;background:red;width:200px;height:200px;} var r=200,dv=0.01,w=100,x=400;y=100,pn=8 var pi=3.1415926575,d=p

  • 基于javascript实现按圆形排列DIV元素(一)

    效果图: 一.分析图: 绿色边框内:外层的DIV元素,相对定位; 白色圆形框:辅助分析的想象形状; 白点:为白色圆形的圆心点,中心点,点o; 圆心角:角NOG; 黄色:需要按圆形排列的,绝对定位的DIV元素; 红色点:为每个黄色DIV的坐标点;即绝对定位时的元素,left值 和 top值 ,设置的点; 二.涉及到的概念定义: 2.1.弧度:弧度是角的度量单位. (红色部分为弧长,角A为弧长对应的圆心角) 弧长等于半径的弧,其所对的圆心角为1弧度.(即两条射线从圆心向圆周射出,形成一个夹角和夹角正

  • JavaScript全排列的六种算法 具体实现

    全排列是一种时间复杂度为:O(n!)的算法,前两天给学生讲课,无意间想到这个问题,回来总结了一下,可以由7种算法求解,其中动态循环类似回溯算法,实现起来比较繁琐,故总结了6种,以飨读者.所有算法均使用JavaScript编写,可直接运行.算法一:交换(递归) 复制代码 代码如下: <html xmlns="http://www.w3.org/1999/xhtml">  <head>      <meta http-equiv="Content-T

  • JS实现数组按升序及降序排列的方法

    本文实例讲述了JS实现数组按升序及降序排列的方法.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>数组数字大小排序</title> </head> <body> <p>让数组按照升序降序排列</p> <p>这里写

  • js实现简单排列组合的方法

    本文实例讲述了js实现简单排列组合的方法.分享给大家供大家参考,具体如下: 运行效果截图如下: 具体代码如下: <!DOCTYPE html> <html> <head> <title>demo</title> <script type="text/javascript"> var str = [1,2,3,4,5]; var count = 0; function arrange(s){ for(var i=0,

  • 基于javascript实现按圆形排列DIV元素(二)

    一.原理分析 1.1怎么才能让DIV元素动起来? 动起来的实质,就是改变DIV的位置,也就是改变其left和top值; 2.2怎么上DIV元素动起来的时候,是在规定的圆周上面? 通过上一次的分析,让DIV按圆形排队,我们知道了,如要让DIV定位在圆周上面,主要是根据角度(弧度)来实现的. 看下图: 上图中,我们B元素和C元素的定位是如何实现的?根据上一次讲的公式,如下: (index:元素的索引值,radius半径,dotLeft:圆心的横坐标,dotTop:圆心的纵坐标) B的left = M

  • JavaScript实现数字数组按照倒序排列的方法

    本文实例讲述了JavaScript实现数字数组按照倒序排列的方法.分享给大家供大家参考.具体如下: 下面的代码演示了JS数组如何通过sort对数字类型的数组进行倒序排序 <!DOCTYPE html> <html> <body> <p id="demo"> Click the button to sort the array. </p> <button onclick="myFunction()"&g

  • JS实现的数组全排列输出算法

    本文实例讲述了JS实现的数组全排列输出算法.分享给大家供大家参考.具体分析如下: 这段js代码对数组进行全排列输出,改进了一些老的代码 从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列.当m=n时所有的排列情况叫全排列. function permute(input) { var permArr = [], usedChars = []; function main(input){ var i, ch; for (i = 0; i < i

  • JS实现二维数组元素的排列组合运算简单示例

    本文实例讲述了JS实现二维数组元素的排列组合运算.分享给大家供大家参考,具体如下: 用js实现二维数组里面的元素排列组合一个小demo: 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3

  • 基于javascript实现按圆形排列DIV元素(三)

    $(this).css({"left":Math.sin((ahd*index+ainhd))*radius+dotLeft,"top":Math.cos((ahd*index+ainhd))*radius+dotTop}); 效果图: 分析图: 上图中: 黑色:是外层容器; 黄色:是需要按椭圆运动的图片 橙色:每个图片元素距离容器顶部的距离 紫色:长半径或短半径; 蓝色:图片距离容器顶部最大的距离 绿色:坐标轴; 白色:椭圆运动轨迹; 一.原理分析: 1.1按椭圆

随机推荐