题目大意:按字典序,求字符串的全排列
解题思路:组合数学的字典序法:
str[0....len-1];
从后往前扫描找到一个严格单调递增的连续子序列设为str[i....len-1],其中str[i] <= str[i-1];
在这个严格单调递增的子序列中,我们再从后往前找出第一个大于str[i-1]的字符,把这个字符和str[i]交换,然后在把str[i....len-1]进行反转。
例如3421
严格单调递增的后缀子序列为421
第一个比3大的数是4,交换3和4得4321,然后反转后面的后缀子序列,得4123则为3421的下一个序列。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 210;
char str[maxn];
void reverse(char *pBegin, char *pEnd);
int main()
{
while(scanf("%s", str) != EOF)
{
int len = strlen(str), i;
sort(str, str + len);
bool flag = false;
do
{
flag = false;
printf("%s\n", str);
for(i = len - 1; i > 0; i--)
{
if(str[i] > str[i - 1])
{
flag = true;
break;
}
}
if(flag)
{
int j;
for(j = len - 1; j >= i; j--)
{
if(str[j] > str[i - 1])
{
char tmp = str[i - 1];
str[i - 1] = str[j];
str[j] = tmp;
break;
}
}
reverse(str + i, str + len - 1);
}
} while(flag);
}
return 0;
}
void reverse(char *pBegin, char *pEnd)
{
while(pBegin < pEnd)
{
char tmp = *pEnd;
*pEnd = *pBegin;
*pBegin = tmp;
pBegin++;
pEnd--;
}
}