I: Carryon的字符串排序(字典树/map映射)

2297: Carryon的字符串
Time Limit: C/C++ 1 s      Java/Python 3 s      Memory Limit: 128 MB      Accepted: 11      Submit: 24
Submit My Status
Problem Description
Carryon最近喜欢上了一些奇奇怪怪的字符,字符都是英文小写字母,但奇怪的是a可能比b小,也可能比b大,好奇怪。与此同时,他拿到了好多的字符串,可是看着很不顺眼,因为他们很乱,所以他想将这些字符串按字典序从小到大排下序,这样就好看多了。由于a可能比b小,也可能比b大,这样按常规方法肯定是不行的,幸运的是他破解了26个字母的大小顺序,这样他就开开心心的将字符串从小到大排序了。

Input
第一行输入2626个字符的大小顺序

第二行输入一个n(1≤n≤105)n(1≤n≤105)。

接下来nn行,每行一个字符串sisi,数据保证每个字符串不重复。(1≤∑i=1nlen(si)≤3×105)(1≤∑i=1nlen(si)≤3×105)
Output
将n个字符串按字典序从小到大输出。

Sample Input
abcdefghijklmnopqrstuvwxyz
5
bcda
licj
lin
aaaa
aaaaa
Sample Output
aaaa
aaaaa
bcda
licj
lin

法一:先将26个字母映射成a~z,然后在输入原串后按映射规则翻译成标准串,再通过标准串排序从而有序输出原串

#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<map>
using namespace std;
map<char,char>mm;
struct node
{
             string s0;//原字符串
             string s1;//映射后的字符串
}p[111111];
bool cmp(node x,node y){
             return x.s1<y.s1;//按标准串从小到大给结构体排序
}
int main()
{
         char s[26];
         scanf("%s",s);
         int len=strlen(s);
         for(int i=0;i<len;i++)
                  mm[s[i]]='a'+i;
         int n;
         scanf("%d",&n);
         for(int i=0;i<n;i++)
         {
                  cin>>p[i].s0;
                  int lenth=p[i].s0.length();
                  for(int j=0;j<lenth;j++)
                  p[i].s1+=mm[p[i].s0[j]];//翻译
                  //cout<<p[i].s1<<endl;
         }
         sort(p,p+n,cmp);//通过s1给p排序                   
         for(int i=0;i<n;i++)
                  cout<<p[i].s0<<endl;
         return 0;
}


法二:建立字典树,然后dfs,先按深度再按与a相差大小找并记录对应字符,每次找到尾结点输出字符串

#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
#define maxn 1111111
using namespace std;
int pos=1;
char s[26],str[maxn];
int t[maxn][26];
bool vis[maxn];
map<char,int>mm;
void insert(char *s)
{
         int rt=0,len=strlen(s);
         for(int i=0;i<len;i++)
         {
                  int x=mm[s[i]];
                  if(!t[rt][x])
                           t[rt][x]=pos++;
                  rt=t[rt][x];
         }
         vis[rt]=1;
}
void dfs(int rt,int deep)
{
         for(int i=0;i<26;i++)
         {
                  if(t[rt][i])
                  {
                           str[deep]=s[i];
                           if(vis[t[rt][i]])//到达尾结点
                           {
                                    str[deep+1]='\0';
                                    printf("%s\n",str);
                           }
                           dfs(t[rt][i],deep+1);
                  }
         }
         return;
}
int main()
{
         scanf("%s",s);
         for(int i=0;i<26;i++)
                  mm[s[i]]=i;
         int n;
         scanf("%d",&n);
         memset(vis,0,sizeof(vis));
         for(int i=0;i<n;i++)
         {
                  char ss[3333333];
                  scanf("%s",ss);
                  insert(ss);
         }
         dfs(0,0);
         return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42060896/article/details/82889756