longeset_common_profix_array(lcp_array,最长公共前缀数组,高度数组)

来源:互联网 发布:淘宝代销货 编辑:程序博客网 时间:2024/06/04 20:02
#include<iostream>#include<vector>#include<algorithm>#include<string>using namespace std;string s;vector<int> sa;vector<int> grade;vector<int> tmpg;int lcp[1000];int k;int n;bool cmpg(int a, int b){    if (grade[a] != grade[b])        return grade[a] < grade[b];    else    {        int nexa = a + k <= n ? grade[a + k] : -1;        int nexb = b + k <= n ? grade[b + k] : -1;        return nexa < nexb;    }}void getsa(){    sa.clear();    grade.clear();    tmpg.clear();    n = s.size();    for (int i = 0; i <= n; i++)    {        sa.push_back(i);        grade.push_back(i < n ? s[i] : -1);    }    tmpg = grade;    for (k = 1; k <= n; k*=2)    {        sort(sa.begin(), sa.end(), cmpg);        tmpg[sa[0]] = 0;        for (int i = 1; i <= n; i++)        {            tmpg[sa[i]] = tmpg[sa[i - 1]] + (cmpg(sa[i-1],sa[i])?1:0);        }        copy(tmpg.begin(), tmpg.end(), grade.begin());    }}void getlcp(){    for (int i = 0; i <= n; i++)    {        grade[sa[i]] = i;    }    int h = 0;    lcp[sa[0]] = 0;    for (int i = 0; i < n; i++)    {        int j = sa[grade[i] - 1];        if (h > 0)            h--;        for (; i + h < n&&j + h < n; h++)            if (s[i + h] != s[j + h])                break;        lcp[grade[j]] = h;    }}int main(){    while (cin >> s)    {        getsa();        getlcp();        for (int i = 0; i < n; i++)            cout << lcp[i] << endl;    }    return 0;}
0 0