UVA 10098 - Generating Fast

按字典序从小到大输出字符串的全排列,白书的7.2刚好讲到生成可重集的排列,所以参考白书上的代码写了个函数,具体操作过程是先将字符串中的所有字符按字典序排序,然后调用print_permutation( len, s, a, 0)即可。

void print_permutation( int len, char *P, char *A, int cur)

{

if( cur == len) {

for( int i = 0; i < len; i ++) printf( "%c", A[i]);

printf( "\n");

}

else for( int i = 0; i < len; i ++) //在A[cur]中填入p[i]

if( !i || P[i] != P[i-1])

{

int c1 = 0, c2 = 0;

for( int j = 0; j < cur; j ++) if( A[j] == P[i]) c1 ++;

for( int j = 0; j < len; j ++) if( P[i] == P[j]) c2 ++;

if( c1 < c2)

{

A[cur] = P[i];

print_permutation( len, P, A, cur + 1);

}

}

}

 

上面的c1是统计A[0]到A[cur-1]中p[i]的出现次数,c2则是P中p[i]的个数。当c1<c2时,我们就能递归调用这些函数。

另外值得注意的是枚举的下标i应不重复、不遗漏的取遍所有的P[i]值,因为P经过排序,所以我们只需要不断P[i]与P[i-1] 是否相等就知道是不是重复了。

完整的程序如下:

#include<cstdio>
#include<cstring>
#include<cstdlib>

char s[15], a[15];
int len;

int cmp( const void *_p, const void *_q)
{
char *p = ( char *)_p;
char *q = ( char *)_q;
return *p - *q;
}


void print_permutation( int len, char *P, char *A, int cur)
{
if( cur == len) {
for( int i = 0; i < len; i ++) printf( "%c", A[i]);
printf( "\n");
}
else for( int i = 0; i < len; i ++)
if( !i || P[i] != P[i-1])
{
int c1 = 0, c2 = 0;
for( int j = 0; j < cur; j ++) if( A[j] == P[i]) c1 ++;
for( int j = 0; j < len; j ++) if( P[i] == P[j]) c2 ++;
if( c1 < c2)
{
A[cur] = P[i];
print_permutation( len, P, A, cur + 1);
}
}
}

int main()
{
int tt;
scanf( "%d", &tt);
while( tt --)
{
scanf( "%s", s);
len = strlen( s);
qsort( s, len, sizeof( char), cmp);
memset( a, 0, sizeof a);
print_permutation( len, s, a, 0);
printf( "\n");
}
return 0;
}

用C++的库函数:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int main()
{
int T;
scanf( "%d", &T);
char s[15];
while( T --)
{
scanf( "%s", s);
int len = strlen( s);
sort( s, s + len);
do
{
printf( "%s\n", s);
}while( next_permutation( s, s + len) );
printf( "\n");
}
return 0;
}

参考一个大牛的写法:

#include<cstdio>
#include<cstring>
#include<cstdlib>

char s[15], a[15];
int len;

int cmp( const void *_p, const void *_q)
{
char *p = ( char *)_p;
char *q = ( char *)_q;
return *p - *q;
}


void dfs( int cur)
{
if( cur == len)
printf( "%s\n", a);

else for( int i = 0; i < len; i ++)
if( !i || s[i] != s[i - 1])
{
int c1 = 0, c2 = 0;
for( int j = 0; j < cur; j ++) if( a[j] == s[i]) c1 ++;
for( int j = 0; j < len; j ++) if( s[i] == s[j]) c2 ++;
if( c1 < c2)
{
a[cur] = s[i];
dfs(cur + 1);
}
}
}

int main()
{
int tt;
scanf( "%d", &tt);
while( tt --)
{
scanf( "%s", s);
len = strlen( s);
memset( a, 0, sizeof a);
qsort( s, len, sizeof( char), cmp);
dfs( 0);
printf( "\n");
}
return 0;
}




你可能感兴趣的:(uva)