九度 1120

题目描述:

给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。
我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列。

输入:

输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。

输出:

输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:
已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。

样例输入:
abc
样例输出:
abc
acb
bac
bca
cab
cba

这题我新接触到了一个全排列函数,是STL的库函数,next_permutation(),有了这个函数全排列问题就变得非常简单了,具体代码如下:
#include <iostream>
#include <cstring>
#include<stdio.h>
#include <algorithm>
using namespace std;

int main()
{
   char s[7];
   while (scanf("%s",s)!=EOF)
   {
      printf("%s\n",s);
      while (next_permutation(s,s+strlen(s)))
         printf("%s\n",s);
      printf("\n");
   }
   return 0;
}

关于全排列函数的相关知识:

          next_permutation是STL中专门用于排列的函数,运行需要包含头文件   
           #include        <algorithm>   
           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, ostream_iterator<int>(cout"\n"));  
                cout<<endl:   

                 ........   
                .......   
       }   

//排序可以用sort()实现

 

首先,给出算法的思路 
设R={r1,r2,...,rn}是要进行排列的n个元素,Ri=R-{ri}。
集合X中元素的全排列记为permutation(X),(ri)permutation(X)表示在全排列permutation(X)的每一个排列前加上前缀ri得到的排列。
R的全排列可归纳定义如下:
当n=1时,permutation(R)={r},r是集合R中唯一的元素;
当n>1时,permutation(R)由(r1)permutation(R1),(r2)permutation(R2),……,(rn)permutation(Rn)构成。

此算法要求待排列的数据是互异的,因为该算法不能检测同种排列是否已经输出,如:
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
 
这是该算法的缺点,也限制了它的适用范围。

http://hi.baidu.com/%B0%AE%D0%C4%CD%AC%C3%CB_%B3%C2%F6%CE/blog/item/566a4d35a31ce61990ef39b6.html