完美全排列

 一、递归全排列(这段排列是可去重的全排列)

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;

int sum=0;
bool isSwap(char *list, int begin, int end) {//避免重复
    for (int i = begin; i < end; i++){
        if (list[i] == list[end])
            return false;
    }
    return true;
}
void SWAP(char *A,int x,int y)//用于交换数组的两个数
{
    int temp=A[x];
    A[x]=A[y];
    A[y]=temp;
}


void perm(char A[], int i, int n){
    int j;
    if (i == n) {
        cout<<A<<endl;
        sum++;
    }
    else {
    for (j = i; j <n; j++){
        if (isSwap(A, i, j)) {
        //使用宏定义,传的是数值,如果这的swap用函数实现,传的应该是指针
        SWAP(A,i,j);
        //交互位置后,输出以list[j]不变,后面的字母改变的所有排列
        perm(A, i + 1, n);
        SWAP(A,i,j);
        }
    }
    }
}
int main()
{
    char s[105];

    while(scanf("%s",s)!=EOF)
	{
        sum=0;
		int len=strlen(s);//数组长度
		perm(s,0,len);
		cout<<sum;

	}

}

二、STL实现

        有时候递归的效率使得我们不得不考虑除此之外的其它实现,非常多把递归算法转换到非递归形式的算法是比较难的,这个时候我们不要忘记了标准模板库已经实现的那些算法,这让我们非常轻松。STL有一个函数next_permutation(),它的作用是假设对于一个序列,存在依照字典排序后这个排列的下一个排列,那么就返回true且产生这个排列,否则返回false。注意,为了产生全排列,这个序列要是有序的,也就是说要调用一次sort。实现非常easy,我们看一下代码:

(1)char数组排列

#include <iostream> 
#include <algorithm>
#include <cstring>
using namespace std;

void permutation(char* str,int length)
{
	sort(str,str+length);
	do
	{
		for(int i=0;i<length;i++)
			cout<<str[i];
		cout<<endl;
	}while(next_permutation(str,str+length));

}
int main(void)
{
	const int n=105;
	char str[n];
	cin>>str;
	cout<<str<<"全部全排列的结果为:"<<endl;
	permutation(str,strlen(str));
	return 0;
}

 (2)string类排列

#include <iostream> 
#include <algorithm>
#include <cstring>
using namespace std;

void permutation(string str,int length)
{
	sort(str.begin(),str.end());//注意这里和char类型的不同
	do
	{
		for(int i=0;i<length;i++)
			cout<<str[i];
		cout<<endl;
	}while(next_permutation(str.begin(),str.end()));//注意

}
int main(void)
{
	string str;
	cin>>str;
	cout<<str<<"全部全排列的结果为:"<<endl;
	permutation(str,str.size());
	return 0;
}

 三、有一定约束条件的全排列

         对数1,2,3,4,5要实现全排序。要求4必须在3的左边,其他的数位置任意。 

            思路:首先使用上面的2种方法之中的一个实现全排列,然后对全排列进行筛选,筛选出4在3左边的排列。

#include <iostream>
#include <algorithm>
using namespace std;
 
void permutation(int* a,int length)
{
	int i,flag;
	sort(a,a+length);
	do
	{
		for(i=0;i<length;i++)
		{
			if(a[i]==3)
				flag=1;
			else if(a[i]==4)     //假设3在4的左边,运行完代码,flag就是2
				flag=2;
		}
		if(flag==1)          //假设4在3的左边,运行完代码,flag就是1
		{
			for(i=0;i<length;i++)
				cout<<a[i];
			cout<<endl;
		}
	}while(next_permutation(a,a+length));
 
}
int main(void)
{
	const int maxt=105;
	int i,a[maxt],n;
	cin>>n;//数组的元素个数 
	for(i=0;i<n;i++)
		cin>>a[i];
	printf("%d以内全部4在3左边的全排列结果为:\n",i);
	permutation(a,n);
	return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值