poj3080多个字符串找最长公共子串 kmp

http://poj.org/problem?id=3080

kmp是改进版的暴力字符串匹配,明确两个概念——子串和子序列,子串就必须是连续的,子序列不一定,dp有一个问题是最长公共子序列,这里求的是公共子串。

kmp算法最主要的就是一个next数组,一个kmp匹配函数。

这道题目的意思就是输入不超过十个字符串,每个字符串的长度不超过60,然后找出最长的公共子串,如果有好几个子串长度相同,就输出字典序最小的,如果公共子串的长度小于3就不输出了(因为是DNA)

思路:以第一个串为基准,找出它所有的子串,用substr,然后再一重循环,这些个子串分别于剩下的那字符串进行kmp匹配,所以一共是三重循环。

#include
using namespace std;

string data[15];
int next[65];

void Get_next(string s,int len)
{
    next[0]=-1;
    int k=-1;
    int i;
    for(i=1;iwhile(k>-1&&s[k+1]!=s[i])
        {
            k=next[k];
            //cout<
        }
        if(s[k+1]==s[i])
            k++;
        next[i]=k;
    }

}

bool kmp(string ptr,int plen,string str,int slen)
{
    int k=-1;
    for(int i=0;iwhile(k>-1&&str[k+1]!=ptr[i])
            k=next[k];
        if(str[k+1]==ptr[i])
            k++;
        if(k==slen-1)
            return true;
    }
    return 0;
}

int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        int m;
        scanf("%d",&m);
        int i,j,k;
        for(i=0;icin>>data[i];
        /*Get_next(data[0],data[0].size());
        for(i=0;i
        string ans="";
        for(i=1;i<=data[0].size();i++)
        {
            for(j=0;j<=data[0].size()-i;j++)
            {
                string op=data[0].substr(j,i);
                Get_next(op,op.size());
                bool flag=0;
                for(k=1;kif(!kmp(data[k],data[k].size(),op,op.size()))
                        flag=1;
                }
                if(!flag)
                {
                    if(ans.size()else
                    if(ans.size()==op.size())
                    ans=min(ans,op);
                }
            }
        }
        if(ans.size()<3)
        cout<<"no significant commonalities"<else
        cout<return 0;
}

☝这是一个乱糟糟也得不到正确结果的代码,╭(╯^╰)╮,主要我不想背板子,但是kmp总感觉理解了,还是敲不出来。

你可能感兴趣的:(数据结构)