现在的位置: 首页 > 综合 > 正文

输出排列

2019年10月17日 ⁄ 综合 ⁄ 共 1581字 ⁄ 字号 评论关闭
#include <iostream>
using namespace std;

int count = 0;
#define MAX 4

void swap( char *a, char *b){
	char tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;
}

/**
* (全排列:A(m,n)且m==n)
* 全排列是这样的:第一个位置有n种方法,第二个位置n-1种方法...
* 从第一个位置开始,循环将每一个后面的值都交换到第一个位置来,
* 每次放好第一个位置之后,递归求解接下来后面的序列的全排列。
* 每次递归用k来指明正在放的是哪个位置。
*
* 每次递归的时候,剩下的元素里面,每个元素都有机会放在第一个位置(交换)。
*/
void permutation(char a[], int n, int begin){
	if(begin == n){
		//递归结束,输出当前排列好的序列
		for(int i=0;i<n;i++)
			cout<<a[i];
		cout<<"  ";
		count++;
	}
	else{
		//注意从位置k开始
		for(int i=begin;i<n;i++){
			swap(&a[begin], &a[i]);
			permutation(a, n, begin+1);    //递归求解位置begin+1开始的全排列
			swap(&a[begin], &a[i]);        //还原
		}
	}
}

/**
* (可重复的全排列)
* 第一个位置有n中方法,第二个位置有n中方法,...第n个位置有n中方法
* 重新声明一个同样大小的数组来存放结果,每次递归用k来指明正在放的
* 是哪个位置。
*/
void permutation_2(char a[], char b[], int begin, int n){
    //n个位置全部放置完成,输出  
	if(begin == n){
		for(int i=0;i<n;i++)
			cout<<b[i];
		cout<<"("<<count<<") ";
		count++;
	}
	else{
		//在第k个位置尝试放置每一个a[i]
		for(int i=0;i<n;i++){
			b[begin] = a[i];
			permutation_2(a,b,begin+1,n); //递归处理第begin+1个位置
		}
	}
}

int number = 0;
void sub_set2(char a[], int n, char b[], int begin, int k){
	if(k == 0){
		//放置完成,输出
		for(int i=0;i<begin;i++)
			cout<<b[i];
		cout<<"("<<number++<< ")  ";
		return;
	}
	
	//在位置begin尝试每一个a[i]
	for(int i=0;i<n;i++){
		b[begin] = a[i];
		sub_set2(a, n, b, begin+1, k-1); //递归下一个位置
	}
}

/**
* {a,b,c,d}: 子排列,A(1,n),A(2,n)...A(n,n) 并且可重复
* 即a,b,c,d, aa,ab,ac,ad,ba,bb,bc,bd, aaa,aab ,aac,aad,aba, abb...
*/
void permutation_3(char a[]){
	char b[MAX];
	count = 0;
	for(int i=1;i<=MAX;i++)
		sub_set2(a, MAX, b, 0, i);
}


int main(){
	char a[MAX] = {'a' ,'b' ,'c' ,'d' };
	char b[MAX];
	
	cout<<"\n=== 全排列 ===" <<endl;
	permutation(a, MAX, 0);
	cout<<"count:" <<count<<endl;
	
	cout<<"\n=== 可重复的全排列 ===" <<endl;
	count = 0;
	permutation_2(a, b, 0, MAX);
	cout<<"count:" <<count<<endl ;
	
	cout<<"\n=== 子全排列 ===" <<endl;
	permutation_3(a);
	return 0;
}

抱歉!评论已关闭.