• 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]='';
                                        printf("%s
    ",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;
    }
    
  • 相关阅读:
    屏蔽Alt+Enter、Ctrl+Alt+Del、Ctrl+Esc等功能键(Windows 98/Me)
    获取本月第一天和最后一天的最简单的写法
    PHP程序员的优化调试技术和技巧
    Windows关机函数ExitWindowsEx使用大全(适用Windows所有操作平台)
    屏蔽Alt+Enter、Ctrl+Alt+Del、Ctrl+Esc等功能键(Windows 98/Me)
    PHP程序员的优化调试技术和技巧
    Ajax,再生还是幻灭好文推荐
    RAID 分类
    Ajax,再生还是幻灭好文推荐
    Windows关机函数ExitWindowsEx使用大全(适用Windows所有操作平台)
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/9893106.html
Copyright © 2020-2023  润新知