• KMP 串的模式匹配 (25分)


    给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出。如果找不到,则输出“Not Found”。

    本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试数据特点如下:

    • 数据0:小规模字符串,测试基本正确性;
    • 数据1:随机数据,String 长度为 1,Pattern 长度为 1;
    • 数据2:随机数据,String 长度为 1,Pattern 长度为 1;
    • 数据3:随机数据,String 长度为 1,Pattern 长度为 1;
    • 数据4:随机数据,String 长度为 1,Pattern 长度为 1;
    • 数据5:String 长度为 1,Pattern 长度为 1;测试尾字符不匹配的情形;
    • 数据6:String 长度为 1,Pattern 长度为 1;测试首字符不匹配的情形。

    输入格式:

    输入第一行给出 String,为由英文字母组成的、长度不超过 10​^6​​ 的字符串。第二行给出一个正整数 N(10),为待匹配的模式串的个数。随后 N 行,每行给出一个 Pattern,为由英文字母组成的、长度不超过 10​^5 的字符串。每个字符串都非空,以回车结束。

    输出格式:

    对每个 Pattern,按照题面要求输出匹配结果。

    输入样例:

    abcabcabcabcacabxy
    3
    abcabcacab
    cabcabcd
    abcabcabcabcacabxyz
    

    输出样例:

    abcabcacabxy
    Not Found
    Not Found

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    const int maxn = 1000100;
    
    int KMP(char *string, char *pattern);
    void buildMatch(char *pattern, int *match);
    
    int main()
    {
        char string[maxn] = {0};
        char pattern[maxn] = {0};
        int n;
        
        scanf("%s", &string);
        scanf("%d", &n);
        
        for (int i = 0; i < n; i++)
        {
            scanf("%s", &pattern);
            int p = KMP(string, pattern);
            if (p != -1)
            {
                printf("%s", string+p);
            }
            else
            {
                printf("Not Found");
            }
            
            if (i < n-1)
            {
                printf("
    ");
            }
        }
        
        return 0;
    }
    
    int KMP(char *string, char *pattern)
    {
        int n = strlen(string);
        int m = strlen(pattern);
        
        if (n < m)
        {
            return -1;
        }
        int *match = (int *)malloc(sizeof(int) * m);
        
        buildMatch(pattern, match);
        
        int s = 0;
        int p = 0;
        while (s < n && p < m)
        {
            if (string[s] == pattern[p])
            {
                s++;
                p++;
            }
            else if(p > 0)
            {
                p = match[p-1] + 1;
            }
            else
            {
                s++;
            }
        }
        
        return (p == m) ? (s - m) : -1;
    }
    
    void buildMatch(char *pattern, int *match)
    {
        int m = strlen(pattern);
        match[0] = -1;
        
        for (int j = 1; j < m; j++)
        {
            int i = match[j-1];
            while( (i >= 0) && (pattern[i + 1] != pattern[j]) )
            {
                i = match[i];
            }
            
            if (pattern[i + 1] == pattern[j])
            {
                match[j] = i + 1;
            }
            else
            {
                match[j] = -1;
            }
        }
    }
     
  • 相关阅读:
    JBoss+MyEclipse+Mysql 的J2EE环境配置。
    编写一个Session EJB
    编写一个MDB (Message Drive Bean)
    轻便的客户端本地文件数据库 SQLite
    SSH(Struts+Spring+Hibernate)Summary/Profile
    Linux test命令
    mysql权限相关
    linux shell 查看进程的可执行程序路径
    添加dns
    Linux的shell变量
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/12006005.html
Copyright © 2020-2023  润新知