全排列算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
调用STL里#include
#include
#include
using namespace std;
const int N = 4;
int arr[N] = {1,2,3,4};
int main()
{
do{
for(int i=0; i < N; i++)
printf("%d ",arr[i]);
putchar('\n');
}while(next_permutation(arr,arr+N));//prev_permutation(arr,arr+ N) 的话arr里的数据按降序排列
return 0;
}
next_permutation是STL中专门用于排列的函数,运行需要包含头文件
#include
using namespace std
next_permutation(start,end)
注意:函数要求输入的是一个升序排列的序列的头指针和尾指针
如果输入的是一个数组例如:
double a[5]
则:
double *start = &a[0];
double *end = &a[5];(实际上数组的最有一个元素应该是a[4],也就是说
end实际指向的应该是数组最有一个元素指针对下
一个指针)end = start+N;
函数输入之所以要求必须是一个升序的排列,原因在于函数运行一次对输入的数组进行移动排列一次后,在函数退出前判断移动后的数组是否升序,如果升序则函数返回BOOL变量false,否则返回true。这样当你输入的是一个升序的排列后,每运行一次函数就对数组进行一次移动得到一个新的排列,函数对数组的移动排列采用递归方式。当所有排列方式都遍历一遍后函数最后一次输出的又是一个升序的排列,也就是和你最先输入的数组一样的排列。
因此你可以用下面结构遍历所有的排列可能:
while ( next_permutation(start,end))//判断是否函数返回true,是责继
//续循环,否则推出说明排列完毕
{
//你要做的处理程序放在此循环内
copy(start,end, o stream_iterator ........ ....... } //排序可以用sort()实现 首先,给出算法的思路 设R={r1,r2,...,r n}是要进行排列的n个元素,R i=R-{r i}。 集合X中元素的全排列记为permutation(X),(ri)permutation(X)表示在全排列permutation(X)的每一个排列前加上前缀r i得到的排列。 R的全排列可归纳定义如下: 当n=1时,permutation(R)={r},r是集合R中唯一的元素; 当n>1时,permutation(R)由(r1)permutation(R1),(r2)permutation(R2),……, (r n)permutation(R n)构成。 此算法要求待排列的数据是互异的,因为该算法不能检测同种排列是否已经输出,如: 1, 1, 2 那么,全排列期望输出是: 1, 1, 2 1, 2, 1 2, 1, 1 但是该算法的输出: 1, 1, 2 1, 2, 1 2, 1, 1 1, 1, 2 1, 2, 1 2, 1, 1 这是该算法的缺点,也限制了它的适用范围。 程序描述如下: #include < iostream > #include < algorithm > using namespace std; //递归产生R[k:n]的所有的排列,元素是互异的 template < class Type > void permutation(Type * R, int k, int n) { if (k == n) { for ( int i = 0 ;i < n; ++ i) cout << R[i] << " \t " ; cout << endl; } else for ( int i = k;i < n; ++ i) { swap(R[k],R[i]); permutation(R,k + 1 ,n); swap(R[k],R[i]); } } 还有一种很简单的方法,使用GP中的方法 该算法是STL中的范型算法,当然效果是很好的,不会出现上面的算法的情况。程序描述如下: //使用泛型算法next_permutation() #include < iostream > #include < vector > #include < algorithm > using namespace std; //产生R[k:n]的所有的排列 template < class Type > void pernutation(Type * R, int k, int n) { vector < Type > myVec; int i,size = n - k; for (i = k;i < n;i ++ ) myVec.push_back(R[i]); //使用next_permutation()函数必须是有序的数据