POJ 3080 Blue Jeans

来源:互联网 发布:手机关屏幕软件 编辑:程序博客网 时间:2024/06/07 21:34

题意:求n个字符串的最长公共串。

求n个字符长度最长公共子串。对于多模式匹配问题,一般是不可以用KMP解决得,因为忒暴力。

思路很简单:我们先按字符串的长度由短到长进行快排。枚举第一个字符串的不同长度子串,判断她是否为下面多有的公共子串?如果是的话,那么我们就表明找到,则比较其长度,如果比已经找到的串长,那么就替换结果串 否则按字典序比较。取字典序考前的,就可以。


    #include<iostream>    #include<cstring>    #include<stdio.h>    #define Max 62    using namespace std;    char text[10][Max], pat[Max];    int n, ma, lenp, next[Max];    void get_next()    {    int i = 0, j = -1;    next[0] = -1;    while (i < lenp)    {    if (j == -1 || pat[i] == pat[j])    {    i ++;    j ++;    next[i] = j;    }    else    {    j = next[j];    }    }    }//求next函数    void KMP()    {    int k, m, i, j;    get_next();    ma = 100;    for (k = 1; k < n; k ++)    {    i = 0;    j = 0;    m = 0;    while (i < 60 && j < lenp)    {    if (j == -1 || text[k][i] == pat[j])    {    i ++;    j ++;    }    else    {    j = next[j];    }    if (j > m)    {    m = j;    }    }    if (m < ma)    {    ma = m;    }    }    }    int main()    {    int t, i;    char result[Max];    scanf("%d", &t);    while (t --)    {    scanf("%d", &n);    for (i = 0; i < n; i ++)// N个串    {    scanf("%s", text[i]);    }    int ans = 0;    for (i = 0; i <= 57; i ++)    {    strcpy(pat, text[0] + i);    //  枚举第一个串的所有后缀串(当然最后2个可以省去)。                                                            //text[0] + i意思就是把text[0]的第i个字符到最后的用pat表示    //cout<<pat<<endl;    lenp = 60 - i;    KMP();                       //  KMP求出这个后缀串与其余所有串的最大匹配。    if (ans < ma)    {    ans = ma;    strncpy(result, text[0] + i, ans);    result[ans] = '\0';    }    else if (ans == ma)    {    //  存在多个最长公共子串,输出字典序最小的,WA了一次。    char tmp[Max];    strncpy(tmp, text[0] + i, ans);    //  复习: strncpy()没有复制最后的'\0'。    tmp[ans] = '\0';    if (strcmp(tmp, result) < 0)    {    strcpy(result, tmp);    }    }    }    if (ans >= 3)    {    printf("%s\n", result);    }    else    {    printf("no significant commonalities\n");    }    }    return 0;    }


0 0