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

全排列问题

2013年10月08日 ⁄ 综合 ⁄ 共 1479字 ⁄ 字号 评论关闭
//方法一,利用STL中的全排列算法
#include<iostream>
#include <algorithm>
using namespace std;
int main(){
int a[] = {1,2,3};
do{
     cout << a[0] << " " << a[1] << " " << a[2] << endl;
}
while (next_permutation(a,a+3));		//next_permutation(a,a+3)该方法是按字典顺序求出序列a+0~a+3的下一个序列并存回到数组中返回true,直到没有下一个序列返回false
return 0;
}
//方法二,利用规律找到下一个排列
//要求输入n(2~9)输出满足要求(1不在第一个位置,2不在第二个位置等)的排列
//效率不高,重在理解取得下一个排列的方法
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
vector<int> fn(vector<int> v){					//按字典顺序找出当前序列的下一个排列
	vector<int> rev = v;
	int s=0;
	int e=0;
	for(int i = rev.size()-1; i>0; i--){		//找到从左数第一个左邻<右邻的左邻下表
		if(rev[i-1] < rev[i]){
			s = i-1;							//s左邻下表
			break;
		}
	}
	for(int j = rev.size()-1; j>0; j--){
		if(rev[s]<rev[j]){						//找到从左数第一个大于rev[s]的值的下表
			e=j;								//e找的的下表
			break;
		}
	}
	char temp = rev[e];						//rev[s] <-->rev[e]交换
	rev[e] = rev[s];
	rev[s] = temp;			
	sort(rev.begin()+s+1,rev.end());		//将rev[s]之后的数进行从小到大的排序
	return rev;
}
int fnj(int n){								//求阶乘,所有全排列的个数,总共循环的次数
	int result = 1;
	for(int i=1;i<=n;i++){
		result = result * i;
	}
	return result;
}
void printv(vector<int> v){					//输出向量中的内容
	for(int i=0; i<v.size(); i++){
		printf("%d ",v[i]);
	}
	cout<<endl;
}
bool right(vector<int> v){					//是否满足1不在第一个位置,2不在第二个位置等要求
	for(int i=1; i<=v.size(); i++){
		if(i == v[i-1]){
//			cout<<i<<"-->"<<v[i-1];
			return false;
		}
	}
	return true;
}
int main(){
	int count;
	cin>>count;							
//	int n = fnj(count);					//也可以用阶乘来控制
	vector<int> test;
	for(int i=1;i<=count;i++){
		test.push_back(i);
	}
	vector<int> retest = test;
	reverse(retest.begin(),retest.end());
	while(1){
		test = fn(test);
		if(right(test))
			printv(test);
		if(test == retest)				//如果到输出到最后一个了,则退出
			return 0;
	}
	return 0;
}

还有许多方法求出全排列(递归求解等)

抱歉!评论已关闭.