生成全排列的省事方法

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


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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值