关于Anagram题解

 

关于Anagram题解

学习STL排列的用法pku1256

Description

给出n个字符串,对于每一个字符串,按字母顺序输出其中字母的所有排列形式,相同的只能出现一次.
注意字母大小顺序为:'A'<'a'<'B'<'b'<...<'Z'<'z'.

Sample Input

3

aAb

abc

acba

Sample Output

Aab

Aba

aAb

abA

bAa

baA

abc

acb

bac

bca

cab

cba

aabc

aacb

abac

abca

acab

acba

baac

baca

bcaa

caab

caba

cbaa

Hint

An upper case letter goes before the corresponding lower case letter.
So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'.

高手解题:

在生成排列之前,需要自定义字母比较规则对字符串中的字母进行排序,STLnext_permutation的谓词版本,一个while循环就搞定了.

可是刚开始犯了低级错误,试图生成strlen(str)!个排列,然后去重,导致严重严重超时.

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

int myPre(const char& a, const char& b)
{
    if (a == b|| a+32 == b || a == b+32)//
只有大小写之分的字母比较

        return a < b;
    else//
不同的字母比较
        return toupper(a) < toupper(b);
}

int main()
{
    int n, len;
    char str[15];
    cin>>n;
    while (n--) {
        scanf("%s", str);
        len = strlen(str);
        sort(str, str+len, myPre);

        printf("%s/n",str);
        while(next_permutation(str, str+len, myPre)){
            printf("%s/n", str);
        }
    }
    return 0;
}

代码:

#include<iostream>

using namespace std;

 

char str[15],temp;

char s[15];

char flag[15];

char save[1000][15];

int           tag[15];

void dfs(int n);

int           len,counter,sc;

 

int main()

{

       int i,j,k,n,m,t;

       scanf("%d",&n);

       while(n--)

       {

              counter = 0 , sc = 0;

              scanf("%s",str);

              len = strlen(str);

              for(i=0;i<len;i++)

              {

                     if(str[i] <= 'Z')       //如果是大写

                            flag[i] = str[i] + 'a' - 'A';

                     else

                            flag[i] = str[i];

              }

              flag[len] = '/0';

 

              for(i=0;i<len;i++)

              {

                     for(j=i+1;j<len;j++)

                     {

                            if(flag[i] > flag[j])

                            {

                                   temp = str[i];

                                   str[i] = str[j];

                                   str[j] = temp;

 

                                   temp = flag[i];

                                   flag[i] = flag[j];

                                   flag[j] = temp;

                            }

                            else if(flag[i] == flag[j])

                            {

                                   if(str[i] > str[j])

                                   {

                                          temp = str[i];

                                          str[i] = str[j];

                                          str[j] = temp;

                                         

                                          temp = flag[i];

                                          flag[i] = flag[j];

                                          flag[j] = temp;                                   

                                   }

                            }

                     }

              }

 

              //sort done

              //printf("%s/n",str);

              for(i=0;i<len;i++)

              {

                     memset(tag,0,sizeof(tag));

                     memset(s,NULL,sizeof(s));

                     counter = 0;

                     dfs(i);

              }

              for(i=0;i<sc;i++)

                     printf("%s/n",save[i]);

 

       }

       return 0;

}

 

void dfs(int n)

{

       int i,j;

 

       s[counter] = str[n];

       counter++;

 

       tag[n] = 1;      //已搜标记

 

       for(i=0;i<len;i++)

       {

              if(tag[i] == 0)

              {

                     dfs(i);

                     tag[i] = 0;

                     counter--;

              }

       }

 

       if(i == len)

       {

              for(j=0;j<sc;j++)

              {

                     if(strcmp(save[j],s) == 0)

                            break;

              }

              if(j == sc)

              {

                     strcpy(save[sc] , s);

                     sc++;

              }

       }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值