题目地址:http://ac.jobdu.com/problem.php?cid=1039&pid=11
时间限制:1 秒 内存限制:32 兆
-
题目描述:
-
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
-
输入:
-
每个测试案例包括1行。
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
-
输出:
-
对应每组数据,按字典序输出所有排列。
-
样例输入:
-
abc
BCA
-
样例输出:
-
abc
acb
bac
bca
cab
cba
ABC
ACB
BAC
BCA
CAB
CBA
思路:1、找出给定字符串的所有排列;
2、对所有排列进行字典排序;
3、去除重复排列,输出答案。
注意:1、必须要去除重复排列,比如输入aab,排序有6种可能:aab,aba,aab,aba,baa,baa;去除重复之后,为3种可能,aab,aba,baa。若不然的话,会判wrong answer。
2、 此题若用C++stl的next_permutation函数,则会超时,所以要自己写全排列的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp( const void *a, const void *b )
{
char* s1 = (char *)a;
char* s2 = (char *)b;
return strcmp(s1, s2);
}
void permutation(char* pStr, char* pBegin);
char s[362890][11];
int count;
int main()
{
char str[11],temp[11];
int n,f,i;
while(scanf("%s",str)!=-1)
{
count = 0;
n = strlen(str);
permutation(str,str); //找出str的所有排列
f = 1;
for(i=1;i<=n;i++)
f = f*i;
qsort(s,f,11*sizeof(char),cmp); //对所有的排列按字典序排序
strcpy(temp,"\0");
for(i=0;i<f;i++)
if(strcmp(temp,s[i])) //去除重复的排列
{
strcpy(temp,s[i]);
printf("%s\n",s[i]);
}
}
return 0;
}
//找出字符串的所有排列,并没有按字典序
//此段代码出自何海涛的《剑指offer》
void permutation(char* pStr, char* pBegin)
{
if(*pBegin == '\0')
{
strcpy(s[count],pStr);
count++;
}
else
{
for(char* pCh = pBegin; *pCh!='\0'; pCh++ )
{
char temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;
permutation(pStr,pBegin+1);
temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;
}
}
}