• 求全排列


    参考:

    1. STL系列之十 全排列(百度迅雷笔试题)

    2. 全排列算法非递归实现和递归实现 (C++)

    3. [算法]列车算法 

    题目要求:

    写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, 
    如 abc 的全排列: abc, acb, bca, dac, cab, cba

    一.全排列的递归实现

    为方便起见,用123来示例下。123的全排列有123、132、213、231、312、321这六种。首先考虑123和132如何得出:它们的最高位都固定为1(或者说以1为前缀),后边跟上{2,3}的全排列(至于{2,3}的全排列怎么求,则靠递归来完成);213和231同理:以2为前缀,后边跟上{1,3}的全排列;312和321:以3为前缀,后边跟上{1,2}的全排列。

    形式化一点的表述——

    E= {e1 , ..., en }表示个元素的集合,我们的目标是生成该集合的所有排列方式。

    Ei E中移去元素以后所获得的集合,

    perm (X) 表示集合中元素的排列方式,

    ei . p e r m(X)表示在perm (X) 中的每个排列方式的前面均加上ei 以后所得到的排列方式。

    举例——

    如果E= {a, b, c},那么E1= {b, c},perm (E1 ) = ( b cc b),e1.perm (E1) = (a b ca c b)。

    对于递归的基本部分,采用= 1。当只有一个元素时,只可能产生一种排列方式,所以perm (E) = ( e),其中中的唯一元素。

    > 1时,perm (E) = e1.perm (E1 ) +e2.perm(E2 ) +e3.perm (E3) + ⋯ +en .perm (En )。这种递归定义形式是采用perm (X) 来定义perm (E), 其中每个包含n- 1个元素。至此,一个完整的递归定义所需要的基本部分和递归部分都已完成。

    也就是说——

    n= 3并且E=(abc)时,按照前面的递归定义可得perm (E) =a.perm ( {bc} ) +b.perm ( {a,c} ) +c.perm ( {ab} )

    同样,按照递归定义有perm ( {bc} ) =b.perm ( {c} ) +c.perm ( {b}),

    所以a.perm ( {bc} )ab.perm ( {c} ) + ac.perm ( {b}) = a b . c ac.b = (a b ca c b)。

    同理可得 b.perm ( {ac}) = ... = (b a cb c a),c.perm ( {ab}) = ... = (c a bc b a)。

    所以perm (E) = (a b ca c bb a cb c a,c a bc b a)。

     1 public class Permutation {
     2     
     3     // 生成arr[k:m]的所有排列方式
     4     private static void perm(char[] arr, int k, int m) {
     5          if (k == m)    // 得到了一个排列方式
     6              System.out.println(Arrays.toString(arr));
     7          else {            
     8              // arr[k:m]有多种排列方式,递归地求出来
     9              for (int i = k; i <= m; i++) {
    10                  char t = arr[i];  arr[i] = arr[k]; arr[k] = t;
    11                  perm(arr, k+1, m);
    12                  t = arr[i];  arr[i] = arr[k]; arr[k] = t;
    13              }
    14          }
    15     }
    16     
    17     private static void perm(char[] arr) {
    18         perm(arr, 0, arr.length-1);
    19     }
    20 
    21     public static void main(String[] args) {
    22         char[] sequence = new String("abcd").toCharArray();
    23         perm(sequence);
    24     }
    25 
    26 }
    View Code

    总结

    找到递归关系,把perm(E)问题转化为n个perm(X)问题,其中每个包含n- 1个元素。

  • 相关阅读:
    尚观寻求帮助
    linux软链接与硬连接
    linux常用命令(三)
    zend 动作控制器
    zend 路由
    ZF组件功能简介
    zend_controller
    linux常用命令(一)
    练习1
    练习1感受:
  • 原文地址:https://www.cnblogs.com/smartjune/p/5525770.html
Copyright © 2020-2023  润新知