`
dyccsxg
  • 浏览: 205302 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类

计算全排列

    博客分类:
  • Java
 
阅读更多

问题描述:计算一组数据的全排列

例如:输入1,2,3时,共有3!个排列数,将其从小到大依次排序可分组如下:
------
  123
  132
------
  213
  231
------
  312
  321
解题思路:求长度为n的source[]数组的第x个排列数,其中 0<=n<n!
1)获取排列数的第一个字符
  假设数组长度为n,那么排列数共有n组,每组(n-1)!个,
  所以第 x 个排列数的首字符为 source[x/(n-1)!]
2)获取下一个字符
  在获取了第一个字符之后,问题降级为求长度为n-1的source[]数组的第x%(n-1)!个排列数,
  因此可重复1)的过程,
  当余数x%(n-1)!==0时,数组source[]中所有未使用数据的次序不变,可终止对1)的循环。

 

package org.demo.algorithm;
/**
 * 计算全排列
 */
public class FullSort{
    /**
     * 测试
     */
    public static void main(String[] args){
        FullSort obj = new FullSort();
        // 
        String[] source = {"r","a","e","p"};
        // 计算阶乘
        int size = obj.factorial(source.length);
        for (int i=0; i<size; i++){
        	// 获取第 i 个排列数
            String value = obj.getValue(source,i);
            System.out.println("[" + i + "] " + value);
        }
    }

    /**
     * 从源数据中获取第 x 个排列数
     */
    public String getValue(String[] source,int x){
        int length = source.length;
        // 标记已使用过的数据[0:未使用,1:已使用]
        byte[] used = new byte[length];
        // 用来存储第 x 个排列数
        StringBuilder result = new StringBuilder();
        // 已确定数据个数
        int count = 0;
        for (int i=1; i<length; i++){
            // 取阶乘
            int size = factorial(length - i);
            // 取整
            int m = x/size;
            // 取余
            x = x%size;
            // 从未使用的数据中获取第 m 个数据
            String data = getElementAt(source,m,used);
            // 添加到排列数中
            result.append(data);
            count++;
            // 余数为零时,
            // 剩余的未使用数据在排列数中的顺序同下标顺序
            if (x == 0){
                break;
            }
        }
        // 添加剩余数据
        for (int i=0; i<length && count<length; i++){
            if (used[i] != 1){
                result.append(source[i]);
                count++;
                used[i] = 1;
            }
        }
        return result.toString();
    }
    /**
     * 计算阶乘
     */
    public int factorial(int n){
        if (n == 0 || n == 1){
            return 1;
        }
        int result = 1;
        for (int i=2; i<=n; i++){
            result = result * i;
        }
        return result;
    }
    /**
     * 从未使用的数据中获取第 m 个数据
     */
    public String getElementAt(String[] source,int m,byte[] used){
        int currentIndex = 0;
        for (int i=0; i<source.length; i++){
            if (used[i] != 1){
                if (currentIndex == m){
                    used[i] = 1;
                    return source[i];
                }
                currentIndex++;
            }
        }
        throw new RuntimeException("--程序异常--");
    }
}

  

输出结果:

[0] raep
[1] rape
[2] reap
[3] repa
[4] rpae
[5] rpea
[6] arep
[7] arpe
[8] aerp
[9] aepr
[10] apre
[11] aper
[12] erap
[13] erpa
[14] earp
[15] eapr
[16] epra
[17] epar
[18] prae
[19] prea
[20] pare
[21] paer
[22] pera
[23] pear

 

分享到:
评论

相关推荐

    一种计算全排列的简易算法

    在给定的标题“一种计算全排列的简易算法”中,我们可以推测这是一种简化版的全排列算法实现。全排列算法通常有多种实现方式,例如深度优先搜索(DFS)、回溯法、栈或者队列等。这种简易算法可能是通过递归或迭代的...

    计算方法习题 适合学生习题参考 设R=(1, 2, .., n),计算R的全排列。

    /*设R=(1, 2, .., n),计算R的全排列。 分治法求解全排列的算法思想: 设R=(1, 2, .., n)的全排列为P(R), 若R=(),则P()=(); 否则,P(R)={(1)P(2, 3, .., n),(2)P(1, 3, .., n), (3)P(2, 1, .., n), .., (n)...

    n阶行列式计算 C语言 实现

    除了上述主要的计算函数外,还有几个辅助函数,如`Num_Factor()`用于计算全排列的数量,`Full_Arrange()`用于生成所有可能的排列,`Resverse_Num()`用于计算逆序数等。 ### 四、总结 通过对给定文件的分析,我们...

    2021—2022年部编版六年级数学上册期中考试题及答案【通用】.pdf

    第七题讨论圆的半径变化对周长和面积的影响,第八题是工程进度的比较,第九题计算全排列的场次,第十题则是比例关系的填空。 判断题部分主要测试学生对数学概念的正确认知,例如两个真分数相乘结果仍然是真分数,...

    阶乘与排列组合算法 各行各业都能用到

    例如,在计算全排列的数量时,如果有n个不同的元素,那么可以形成n!种不同的排列。 接着,我们探讨排列。排列是将n个不同元素按照一定的顺序排列起来的方式。如果从n个不同的元素中选取k个元素进行排列,那么排列的...

    生成全排列矩阵.zip

    全排列矩阵是数学中的一种重要概念,特别是在组合数学和计算机科学中有着广泛的应用。它指的是一个有限序列的所有可能排列方式组成的矩阵。例如,对于数字序列1, 2, 3,其全排列包括(1, 2, 3), (1, 3, 2), (2, 1, 3)...

    全排列算法解析(完整版)

    对于大型数据集来说,生成全排列是不现实的,因为它需要巨大的计算量和存储空间。对于输出所有排列的情况,时间复杂度为O(n*n!),因为每个排列需要输出n个元素。 除了基本的全排列算法,本文还介绍了字典序排列算法...

    局部搜索解决全排列问题

    全排列问题是一个典型的组合问题,具有较高的计算复杂度。 全排列的核心思想是递归。递归是一种函数或程序调用自身的技术,它在此问题中的应用是通过不断添加新的元素到已排列好的子序列中,从而逐步构建完整的排列...

    python常规方法实现数组的全排列

    了解如何有效地计算全排列对于理解和解决问题至关重要,尤其是在处理小规模数据时。然而,随着元素数量的增加,全排列的数量呈指数级增长,因此在处理大数据时需考虑效率和性能。对于大规模数据,可能需要采用更高效...

    山东省枣庄市薛城区2020_2021学年高二数学下学期期中试题202105240313

    例如,甲、乙、丙三人夺冠的情况数可以通过计算全排列来得到。 4. **函数的性质** - 函数的值计算通常涉及代数运算,如求解函数关系式。 5. **计数原理** - 组合三位奇数时,考虑到个位数必须是奇数,百位和十位...

    C++全排列中递归交换法实例详解

    `main`函数负责读取输入的n值,初始化数组a,并调用`permutation`函数开始计算全排列。 时间复杂度方面,由于我们需要对n个位置进行递归,并且在每一步都要遍历x到n,所以总的时间复杂度为O(n!),这是因为全排列的...

    全排列算法

    全排列的总数可以通过阶乘来计算,即n!。 C++中实现全排列的基本思路是:对于给定的序列,我们首先选择一个元素作为当前排列的第一个元素,然后对剩下的元素进行全排列。这个过程可以使用递归来实现。以下是一个...

    图论- 生成树- 生成树计数.rar

    卡特兰数在生成树计数中起着重要作用,它是组合数学中的一类特殊数,可以用来计算全排列中避免相邻重复的排列数量,而这正是计算无向图生成树数量的关键。卡特兰数C(n)的递推公式为C(n) = (2n)! / [(n+1)! * n!],...

    普及组CSP-J第六套模拟试题模拟题附答案

    - **解决思路**:通过计算全排列总数减去不符合条件的情况。 - **计算过程**:首先计算6个人的全排列数\(A(6,6)\),然后减去甲在最左端的排列数\(A(5,5)\)和乙在最右端的排列数\(A(5,5)\),最后加上甲在最左端同时乙...

    python练习fibonacci全排列

    总结起来,"python练习fibonacci全排列"这个主题涵盖了基础的算法知识,包括Fibonacci数列的不同计算方法和全排列问题的解决策略。通过学习和实践这些内容,可以提升对算法的理解和应用能力,有助于在实际编程项目中...

    生成全排列 C语言 递归的

    C语言的全排列 注意 当n&gt;10 效率会非常低

    分治法解决全排列问题

    分治法解决全排列问题 计算算法分析算法设计

    objective-c数组全排列算法

    在iOS开发中,Objective-C是一种常用的编程语言,用于构建iPhone、iPad等Apple设备的应用程序。...),随着元素数量的增加,计算量会迅速增大,因此在处理大数据量时,应考虑优化或寻找更高效的解决方案。

    全排列算法解析(完整版)

    ### 全排列算法解析 #### 1. 全排列的定义和公式 全排列是指从一个包含`n`个不同元素的集合中选取...随着计算机硬件的发展,虽然全排列的计算仍然受限于其指数级的时间复杂度,但在特定场景下仍具有重要的实用价值。

    计算机数据结构-全排列回溯算法-java

    在Java中,全排列通常通过递归实现,配合回溯算法来避免重复计算。 回溯算法是一种“走一步,退一步”的搜索策略,它尝试分步解决问题,并在每一步中尝试所有可能的选择。如果当前选择无法导出有效的解,算法会撤销...

Global site tag (gtag.js) - Google Analytics