zoukankan      html  css  js  c++  java
  • 求一个集合S中m个元素的所有排列以及一个数组A的全排列—递归实现版完整代码

      说明,本文全文代码均用dart语言实现。

      求一个集合S中m个元素的所有排列情况,并打印,非常适合用递归的思路实现。本文给出了两种实现方法,一种是给定的填充排列数组长度是固定的,一种是可变长度的。两种方法主要思路是一样的,只是实现细节上略有差异。具体代码如下:

     1 void permute<E>(Set<E> s, int m) {
     2   if (m < 0 || m > s.length) throw StateError('m is not in [0, ${s.length}]');
     3 
     4   _fill(<E>[], s, m);
     5   print('-------------------');
     6   _fillFixed(List<E>(m), s, 0, m);
     7 }
     8 
     9 10 
    11 void _fill<E>(List<E> pm, Set<E> s, int m) {
    12   if (pm.length < m) {
    13     for (var e in s) {
    14       pm.add(e);
    15       _fill(pm, _rest(s, e), m);
    16     }
    17   } else {
    18     print(pm);
    19   }
    20   if (pm.isNotEmpty) pm.removeLast();
    21 }
    22 
    23 void _fillFixed<E>(List<E> pm, Set<E> s, int i, int m) {
    24   if (i < m) {
    25     for (var e in s) {
    26       pm[i] = e;
    27       _fillFixed(pm, _rest(s, e), i + 1, m);
    28     }
    29   } else {
    30     print(pm);
    31   }
    32 }
    33 
    34 Set _rest<E>(Set<E> s, E e) {
    35   var t = s.toSet();
    36   t.remove(e);
    37   return t;
    38 }

      如果求一个集合的全排列,如果是集合的话,其实在上面的函数permute,将m的值设为集合s的长度即可:

    1 void permuteAll2<E>(Set<E> s) => permute(s, s.length);

      如果求一个数组的全排列情况(假设数组中元素不重合),可以不像集合那样,还需要额外申请空间,直接利用数组本身即可完成:

     1 void permuteAll(List a, int k) {
     2   if (k < a.length - 1) {
     3     for (int i = k; i < a.length; i++) {
     4       if (i != k) _swap(a, k, i);
     5       permuteAll(a, k + 1);
     6       if (i != k) _swap(a, k, i);
     7     }
     8   } else {
     9     print(a);
    10   }
    11 }
    12 
    13 void _swap(List a, int i, int j) {
    14   var t = a[i];
    15   a[i] = a[j];
    16   a[j] = t;
    17 }

      具体思路,比较简单,直接查看代码即可,或者参照网上的讲解,这里不再赘述了。有兴趣的也可以直接debug,可以看每一步的操作。

      最后,验证代码如下:

    1 void main() {
    2   var s = {1, 2, 3};
    3   permute(s, 3);
    4   print('---------------------
    ');
    5   permuteAll(s.toList(), 0);
    6   print('---------------------
    ');
    7   permuteAll2(s);
    8 }
  • 相关阅读:
    板子们~缓慢更新
    Hello World!
    [SHOI2008]堵塞的交通traffic
    [JSOI2008]最大数
    [SCOI2005]扫雷
    [HAOI2007]上升序列
    [HAOI2007]理想的正方形
    [SCOI2003]字符串折叠
    [HAOI2008]移动玩具
    [BJOI2006]狼抓兔子
  • 原文地址:https://www.cnblogs.com/outerspace/p/10858209.html
Copyright © 2011-2022 走看看