输出字符串的全排列

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

/*
利用字典序算法求字符串的全排列.
对于数字1、2、3......n的排列,不同排列的先后关系是
从左到右逐个比较对应的数字的先后来决定的。
例如:对于5个数字的排列12354和12345,排列12345在前,
排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,
最后面的是54321。
-----------------------------------------------------------
算法步骤如下:
(1)从字符串的最右端开始扫描,找到下标
j满足:j=max{i|pi<pi+1},即找到第一个数
的下标,使得pj<pj+1.
(2)从j的右边开始查找,找到下标
k满足:k=max{i|pi>pj},即找到j右边的,所有比pj大
的数字中的最小数的下标。
(3)交换j和k所指字符,逆序j+1至n处的字符。就得到下一个
全排列。
*/
void next_permut(string &str);
void reveser(string &str,size_t start);
void all_permut(string &str);

int main()
{
   string str="12345";

    all_permut(str);
    return 0;
}


void next_permut(string &str)
{
 //循环这样子编写是由字典序决定的

 size_t j;//步骤(1)记录下标j

 for(size_t i=str.length()-1;i>=1;--i)
     {
          if(str[i-1]<str[i])
          {
              j=i-1;
              break;
          }
     }

 size_t k;//步骤(2)记录k
  for(size_t i=j+1;i!=str.length();++i)
  {
      if(str[j]<str[i])
         k=i;
  }

  //步骤(3)
  swap(str[j],str[k]);
  reveser(str,j+1);
}

//start表示需要逆转的下标起始点
void reveser(string &str,size_t start)
{
for(size_t i=start,j=str.length()-1;i<j;++i,--j)
   swap(str[i],str[j]);

}

void all_permut(string &str)
{
 sort(str.begin(),str.end());//保证字典序
 string tmp(str);
 reveser(tmp,0);//字典序的最后一个排列

 cout<<str<<endl;//第一个字典序排列输出

 while(str!=tmp)
    {
        next_permut(str);
        cout<<str<<endl;
    }

}

你可能感兴趣的:(输出字符串的全排列)