1. 递归

先排序,flag标记数组(是否已排列),index已排列长度

若未排完,遍历标记数组,找到字符并插入,改变标记

递归调用,调用完后记得恢复标记

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

const int maxn=8;
bool flag[maxn];
char s[maxn];
void getpermutation(string str,int index){//递归
  if(index==str.size()){//已排完:输出
    for(int i=0;i<str.size();i++){
      printf("%c",s[i]);
    }
    printf("\n");
  }
  else{
    for(int i=0;i<str.size();i++){//找到排在最前面且没被放入的
      if(flag[i])continue;
      flag[i]=true;//标记已放入
      s[index]=str[i];//插入
      getpermutation(str,index+1);//递归调用直至排完
      flag[i]=false;//标记未被放入,排更大的字符
    }
  }
}

int main() {
    string str;
    while(cin>>str){
      sort(str.begin(),str.end());//先按升序排列
      getpermutation(str,0);
      printf("\n");
    }
    return 0;
}

2. 非递归

找到逆序排列前一个字符(位置记为Index)、逆序排列中第一个比其大的元素

交换,逆置逆序部分

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

bool getnext(string &str){//寻找下一个
  int n=str.size();
  int index=n-2;//降序排列的前一个字符位置
  while(index>=0&&str[index]>str[index+1])index--;
  if(index<0)return false;
  for(int i=n-1;i>index;i--){
    if(str[i]>str[index]){
      swap(str[i],str[index]);//找到第一个比该字符大的,并交换
      break;
    }
  }
  reverse(str.begin()+index+1,str.end());//将降序反转为升序
  return true;
}

int main() {
    string str;
    while(cin>>str){
      sort(str.begin(),str.end());
      do{
        cout<<str<<endl;
      }while(getnext(str));
		cout<<endl;
    }
    return 0;
}

3. 系统自带

  • prev_permutation(str.begin(),str.end()) 上个排列
  • next_permutation(str.begin(),str.end()) 下个排列
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main() {
    string str;
    while(cin>>str){
      sort(str.begin(),str.end());
     
      do{
        cout<<str<<endl;
      }while(next_permutation(str.begin(),str.end()));
        cout<<endl;
    }
    return 0;
}