zoukankan      html  css  js  c++  java
  • Corporate Identity

    题目大意:给你N(2-4000)个字符串,求出来他们的共同子串
     
    分析:因为上次就说了再出现这种题就不用那种暴力的做法了,于是看了一些别的知识,也就是后缀树,把一个字符串的所有的后缀全部都加入字典树,然后用别的串去匹配,这样匹配的时候速度那是飕飕的啊,不过第一次我把前N-1个串的所有前缀搞进了字典树里面,然后想如果某个节点被访问N-1次,并且第N个串也能访问到此节点,那么这一定就是他们的共同子串了,不过总归是太天真,直接返回MLE,一细琢磨,想着最糟糕的情况也就是有8000(N)个串,每个串都不相同,并且每个串的长度是200(len),那么空间复杂度应该是 len*(len+1)/2*N*26 大约理论上最糟糕的情况就是41亿内存,不超才见鬼了呢于是又换一种想法,如果只把第一个串的所有后缀加入字典树不就行了?因为求的是共同子串,第一个串也肯定包括所有串的共同子串,这样内存开销就会降到len*(len+1)/2*26大约50w不到,比较容易接受了。
     
    下面是AC代码:
    ==========================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<stdlib.h>
    using namespace std;
    
    const int MAXN = 26;
    const int MAXM = 1007;
    const int oo = 1e9+7;
    
    struct node
    {
        int times;
        node *next[MAXN];
    };
    
    int BuildTrie(node *head, char s[], int x)
    {
        int i, k, depth = 0;
        node *P = head;
    
        for(i=0; s[i]; i++)
        {
            k = s[i] - 'a';
            if(P->next[k] == NULL)
            {
                if(x != 1)
                    break;
                P->next[k] = new node();
            }
    
            P = P->next[k];
    
            if(P->times + 1 >= x)
            {///如果此节点是本个串访问过或者上个节点访问过
                P->times = x;
                depth++;
            }
            else break;
        }
    
        return depth;
    }
    void clearTrie(node *head)
    {///销毁树
        node *P = head;
    
        for(int i=0; i<MAXN; i++)
        {
            if(P->next[i] != NULL)
                clearTrie(P->next[i]);
        }
    
        free(P);
    }
    
    int main()
    {
        int i, j, N;
    
        while(scanf("%d", &N), N)
        {
            node *head = new node();
            char s[MAXM]={0}, ans[MAXM]={0};
    
            for(i=1; i<N; i++)
            {
                scanf("%s", s);
                for(j=0; s[j] != ''; j++)
                    BuildTrie(head, s+j, i);
            }
            scanf("%s", s);
    
            int Max = 0;
    
            for(j=0; s[j] != ''; j++)
            {
                int len = BuildTrie(head, s+j, N);
                char p[MAXM] = {0};
    
                strncpy(p, s+j, len);
    
                if(Max < len || (Max==len && strcmp(ans, p) > 0))
                    strcpy(ans, p), Max = len;
            }
    
            if(ans[0] == 0)
                printf("IDENTITY LOST
    ");
            else
                printf("%s
    ", ans);
    
            clearTrie(head);
        }
    
        return 0;
    }
  • 相关阅读:
    模板方法模式
    Centos 6.4 python 2.6 升级到 2.7
    Python 在Visual studio 中做单元测试进行TDD开发
    C# 代码转换到Python
    VMware Network Adapter VMnet1和VMnet8 未识别的网络的解决方法
    Visual Studio 启动加速
    查询Sqlserver 表结构信息 SQL
    HTTP发送请求模拟
    【Xamarin 开发 IOS --使用 Storyboard Segue 实作 UIViewController 的切换 (实例)】
    【Xamarin 开发 IOS --IOS 页面导航概念Segue】
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4741283.html
Copyright © 2011-2022 走看看