生成全排列的省事方法

来源:互联网 发布:淘宝显示被挤爆了 编辑:程序博客网 时间:2024/05/22 04:55

生成一个数的全排列,对很多人来说都不是难事。通过递归或非递归的方式,可以生成全排列。对于一些题目的暴力解法是必不可少的。下面总结了几种生成全排列的方式。


1.递归不交换式(dfs):

void dfs(int dep){    if (dep>n) { check(); return;}for (int i=1;i<=n;i++)if (!vis[i]){   vis[i]=1;   a[dep]=i;   dfs(dep+1);   vis[i]=0;  }}


2 非递归交换式(用到了swap(),速度好像比DFS慢):

#include <iostream>  #include <cstring>  using namespace std;    //交换数组a中下标为i和j的两个元素的值  void swap(int *a,int i,int j)  {      a[i]^=a[j];      a[j]^=a[i];      a[i]^=a[j];  }    //将数组a中的下标i到下标j之间的所有元素逆序倒置  void reverse(int a[],int i,int j)  {      for(; i<j; ++i,--j) {          swap(a,i,j);      }  }    void print(int a[],int length)  {      for(int i=0; i<length; ++i)          cout<<a[i]<<" ";      cout<<endl;  }    //求取全排列,打印结果  void combination(int a[],int length)  {      if(length<2) return;        bool end=false;      while(true) {          print(a,length);            int i,j;          //找到不符合趋势的元素的下标i          for(i=length-2; i>=0; --i) {              if(a[i]<a[i+1]) break;              else if(i==0) return;          }            for(j=length-1; j>i; --j) {              if(a[j]>a[i]) break;          }            swap(a,i,j);          reverse(a,i+1,length-1);      }  }  int main(int argc, char **argv)  {      int a[4] = {1, 2, 3, 4};      combination(a, sizeof(a) / sizeof(int));        return 0;  }  

3:递归交换式(同2):

#include <iostream>  using namespace std;    template<typename T>  void permutation(T array[], int begin, int end)  {      int i;        if(begin == end){          for(i = 0; i <= end; ++i){              cout<<array[i]<<" ";          }          cout<<endl;          return;      } else {          //for循环遍历该排列中第一个位置的所有可能情况          for(i = begin; i <= end; ++i) {              swap(array[i], array[begin]);              permutation(array, begin + 1, end);              swap(array[i], array[begin]);          }      }  }    int main(int argc, char **argv)  {      int a[4] = {1, 2, 3, 4};      permutation(a, 0, sizeof(a) / sizeof(int) - 1);        return 0;  }  

4:分分钟式(STL,NB!)

#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>using namespace std;int n,num[1005];int main(){scanf("%d",&n);for(int i=0;i<n;i++)num[i]=i;do{for(int i=0;i<n;i++)printf("%d ",num[i]);printf("\n");}while(next_permutation(num,num+n));return 0;}

看到底,跪了,STL太NB了!功能强大!但要注意,STL有时不开优化的话效率比较低,应该谨慎使用,但毕竟用到全排列时一般是暴力,也就无所谓了~

部分代码引自:http://blog.csdn.net/e3399/article/details/7543861,在此表示感谢,虽然他不一定知道~

1 0
原创粉丝点击